我想解决最小生成树问题的更难版本。
有N
个顶点。此外,还有2M
个边,编号为1,2,..,2M
。图表是连接的,无向的和加权的。我想选择一些边缘使图形仍然连接,并使总成本尽可能小。有一个限制:由2k
编号的边和由2k-1
编号的边是绑定,因此应选择两者或不应选择两者。所以,如果我想选择边3,我也必须选择边4。
那么,连接图表的最低总成本是多少?
我的想法:
2k
和2k+1
称为边集。如果两个边都有效,让我们调用边集 good 。
首先准确添加m
边缘集,这些边集在增加成本的顺序上是好的。然后以递增的成本顺序迭代所有边集,并在至少一个边有效时添加集。 m
应该从0迭代到M
。
运行带有一些变化的kruskal算法:边e
的成本会有所不同。
e
的边集是好,则费用为:(边集的费用)/ 2 。抱歉英语不好,但我想解决这个问题。它是NP难的还是什么,还是有一个很好的解决方案? :D先谢谢你!
答案 0 :(得分:0)
我不确定它是否是最佳解决方案,但我的第一种方法是使用回溯搜索:
这很有效,但速度慢,不够优雅。虽然可以通过一些调整来避免不必要的分支,但可以挽救这种方法。
首先,仍然可以移除的边缘对是一个只有在深入时才会收缩的集合。因此,在下一次递归中,您只需要检查前一组可能可移除边对中的那些。此外,由于删除边对的顺序并不重要,因此您不应考虑之前已考虑过的任何边对。
然后,检查两个节点是否连接是昂贵的。如果为边缘缓存备用路由,则可以相对快速地检查该路由是否仍然存在。如果它没有,你必须运行昂贵的支票,因为即使这一条路线不复存在,也可能还有其他路线。
然后,对树进行一些修剪:您的可移动边缘对的集合给出了最佳解决方案所具有的权重的下限。此外,任何现有解决方案都给出了最优解的上限。如果一组可移动边缘甚至没有机会找到比之前最好的解决方案更好的解决方案,那么你可以停在那里并回溯。
最后,要贪心。使用常规贪婪算法不会为您提供最佳解决方案,但它会迅速提高任何解决方案的标准,使修剪更有效。因此,尝试按重量减轻的顺序移除边缘对。
答案 1 :(得分:0)
正如我之前推测的那样,这个问题是NP难的。我不确定是不合适的;有一个非常简单的2近似(将每对分成两半,保留两半的全部成本,并运行您最喜欢的香草MST算法)。
给出这个问题的算法,我们可以解决NP-hard Hamilton循环问题如下。
设G =(V,E)为Hamilton循环的实例。克隆所有其他顶点,表示vi'的vi克隆。我们复制每个边e = {vi,vj}(制作一个多图;我们可以用简单的图形以清晰度为代价进行这种缩减),并且,让v0成为任意原始顶点,我们将一个副本与{v0,vi配对'}和另一个{v0,vj'}。
没有MST可以使用少于n对,一个用于将每个克隆顶点连接到v0。有趣的是,像这样具有n对的候选对的另外一半可以被解释为G的定向子图,其中每个顶点具有out-degree 1(使用克隆位中的索引作为尾部)。此图表连接原始顶点,当且仅当它们是汉密尔顿循环时。
有多种方法可以应用整数编程。这是一个简单的,一个更复杂的。首先,如果选择了边对x_i
,我们为i
的每个1
制定一个二进制变量2i-1, 2i
。问题模板看起来像
minimize sum_i w_i x_i (drop the w_i if the problem is unweighted)
subject to
<connectivity>
for all i, x_i in {0, 1}.
当然我遗漏了有趣的限制:)。实施连接的一种方法是首先解决这个没有约束的公式,然后检查解决方案。如果它是连接的,那么很棒 - 我们已经完成了。否则,找到一组顶点S
,使S
与其补码之间没有边,并添加约束
sum_{i such that x_i connects S with its complement} x_i >= 1
并重复。
另一种方法是在解算器内部生成约束,从而处理整数程序的线性松弛。通常,MIP库具有允许此功能的功能。然而,分数问题具有分数连通性,这意味着找到最小切割以检查可行性。我希望这种方法更快,但我必须道歉,因为我没有精力描述它的细节。