Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 具有两条边的最小生成树_Algorithm_Graph_Minimum Spanning Tree - Fatal编程技术网

Algorithm 具有两条边的最小生成树

Algorithm 具有两条边的最小生成树,algorithm,graph,minimum-spanning-tree,Algorithm,Graph,Minimum Spanning Tree,我想解决一个更难的最小生成树问题 有N个顶点。还有2M边,编号为1、2、…,2M。图是连通的、无向的和加权的。我想选择一些边,使图仍然连接,使总成本尽可能小。有一个限制:编号为2k的边和编号为2k-1的边是并列的,因此应选择两者或不选择两者。所以,如果我想选择边3,我也必须选择边4 那么,使图连接起来的最小总成本是多少 我的想法: 让我们将两条边2k和2k+1称为边集 如果一条边合并了两个不同的组件,我们就称它为有效边 如果两条边都有效,我们就称边集为good 首先准确地添加m边集,这些边集按

我想解决一个更难的最小生成树问题

N个
顶点。还有
2M
边,编号为1、2、…,
2M
。图是连通的、无向的和加权的。我想选择一些边,使图仍然连接,使总成本尽可能小。有一个限制:编号为
2k
的边和编号为
2k-1
的边是并列的,因此应选择两者或不选择两者。所以,如果我想选择边3,我也必须选择边4

那么,使图连接起来的最小总成本是多少

我的想法:

  • 让我们将两条边
    2k
    2k+1
    称为边集
  • 如果一条边合并了两个不同的组件,我们就称它为有效边
  • 如果两条边都有效,我们就称边集为good

  • 首先准确地添加
    m
    边集,这些边集按成本的递增顺序排列。然后按成本递增的顺序迭代所有边集,如果至少有一条边有效,则添加该集
    m
    应该从0迭代到
    m

  • 运行一个kruskal算法,但要有一些变化:边
    e
    的成本是不同的

    • 如果包含
      e
      的边集是好的,则代价为:(边集的代价)/2
    • 否则,成本为:(边集的成本)
    • 即使成本发生变化,我也无法证明kruskal算法是否正确

对不起,英语不好,但我想解决这个问题。是NP难还是什么,或者有好的解决方案D提前感谢你

我不确定这是否是最好的解决方案,但我的第一种方法是使用回溯搜索:

  • 在所有边对中,标记那些可以在不断开图形连接的情况下删除的边对
  • 移除其中一个集合,并为剩余的图找到最佳解决方案
  • 把这一对放回去,换掉下一对,找到最好的解决办法
  • 这是可行的,但速度慢且不公平。虽然可以通过一些避免不必要分支的调整来挽救这种方法

    首先,仍然可以删除的边对是一组仅在深入时缩小的边对。因此,在下一个递归中,您只需要检查前一组可能的可移动边对中的那些。此外,由于移除边缘对的顺序并不重要,所以不应该考虑以前已经考虑过的任何边缘对。 然后,检查两个节点是否连接是昂贵的。如果缓存边的替代路由,则可以相对快速地检查该路由是否仍然存在。如果它不存在,你必须运行昂贵的检查,因为即使一条路线不存在,也可能还有其他路线

    然后,对树进行更多的修剪:您的可移动边对集为最佳解决方案的权重提供了一个下限。此外,任何现有解都给出了最优解的上界。如果一组可移动的边甚至没有机会找到比以前最好的解决方案更好的解决方案,那么您可以停下来回溯


    最后,要贪婪。使用常规的贪婪算法不会给你一个最优的解决方案,但它会迅速提高任何解决方案的门槛,使修剪更加有效。因此,尝试按重量减少的顺序删除边缘对。

    我不确定这是否是最佳解决方案,但我的第一种方法是使用回溯搜索:

  • 在所有边对中,标记那些可以在不断开图形连接的情况下删除的边对
  • 移除其中一个集合,并为剩余的图找到最佳解决方案
  • 把这一对放回去,换掉下一对,找到最好的解决办法
  • 这是可行的,但速度慢且不公平。虽然可以通过一些避免不必要分支的调整来挽救这种方法

    首先,仍然可以删除的边对是一组仅在深入时缩小的边对。因此,在下一个递归中,您只需要检查前一组可能的可移动边对中的那些。此外,由于移除边缘对的顺序并不重要,所以不应该考虑以前已经考虑过的任何边缘对。 然后,检查两个节点是否连接是昂贵的。如果缓存边的替代路由,则可以相对快速地检查该路由是否仍然存在。如果它不存在,你必须运行昂贵的检查,因为即使一条路线不存在,也可能还有其他路线

    然后,对树进行更多的修剪:您的可移动边对集为最佳解决方案的权重提供了一个下限。此外,任何现有解都给出了最优解的上界。如果一组可移动的边甚至没有机会找到比以前最好的解决方案更好的解决方案,那么您可以停下来回溯


    最后,要贪婪。使用常规的贪婪算法不会给你一个最优的解决方案,但它会迅速提高任何解决方案的门槛,使修剪更加有效。因此,尝试按重量损失的顺序移除边缘对。

    正如我之前推测的,这个问题是NP难的。我不确定是否不合适;有一个非常简单的2-近似(将每一对分成两半,保留两半的全部成本,并运行您最喜欢的香草MST算法)

    给出这个问题的一个算法,我们可以如下解决NP难的Hamilton圈问题

    设G=(V,E)为Hamilton循环的实例。克隆所有其他顶点,表示通过vi'克隆vi。我们复制每条边e={vi,vj}(生成一个多重图;我们可以用简单的
    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}.
    
    sum_{i such that x_i connects S with its complement} x_i >= 1