包含给定节点集的最小连通子图

时间:2010-10-20 07:52:15

标签: algorithm graph graph-theory subgraph graph-algorithm

我有一个未加权的连接图。我想找到一个连接的子图,它肯定包含一组特定的节点,并且尽可能少的附加内容。怎么能实现呢?

为了以防万一,我将使用更精确的语言重述问题。设G(V,E)为未加权,无向连通图。设N是V的某个子集。找到G(V,E)的最小连通子G'(V',E')的最佳方法是什么,这样N是V'的子集?

近似值很好。

4 个答案:

答案 0 :(得分:9)

这正是众所周知的NP难Steiner Tree问题。如果没有关于实例的详细信息,很难就适当的算法提供建议。

答案 1 :(得分:5)

我无法想到找到最佳解决方案的有效算法,但假设您的输入图形密集,以下内容可能效果不错:

  1. 将输入图G(V, E)转换为加权图G'(N, D),其中N是要覆盖的顶点子集,D是距离(路径)原始图中相应顶点之间的长度)。这将“折叠”您不需要的所有顶点到边缘。

  2. 计算G'

  3. 的最小生成树
  4. 通过以下过程“展开”最小生成树:对于最小生成树中的每个边d,采用图G中的相应路径并添加所有顶点(包括端点) )在结果集V'的路径上以及结果集E'的路径中的所有边。

  5. 此算法很容易绊倒以提供次优解决方案。示例案例:等边三角形,其中在拐角处,在边的中点和三角形的中间存在顶点,并且沿着边的边缘以及从角的边缘到三角形的中间。为了覆盖角落,它足以选择三角形的单个中点,但是这个算法可能会选择边。尽管如此,如果图表密集,它应该可以正常工作。

答案 2 :(得分:3)

最简单的解决方案如下:

a)基于mst:     - 最初,V的所有节点都在V'     - 构建图G(V,E)的最小生成树 - 称之为T.
    - loop:对于不在N中的T中的每个叶v,从V'中删除v     - 重复循环,直到T中的所有叶子都在N.

b)另一种解决方案如下 - 基于最短路径树     - 选择N中的任何节点,将其称为v,让v为树的根T = {v}。     - 从N中删除v。

  • 循环: 1)从T中的任何节点和N中的任何节点中选择最短路径。最短路径p:{v,...,u}其中v在T中,u在N中。  2)p中的每个节点都加到V'。  3)从N中删除p和N中的每个节点。 ---重复循环,直到N为空。

在算法开始时:使用任何已知的有效算法计算G中的所有最短路径。

就个人而言,我在我的一篇论文中使用过这种算法,但它更适合分布式环境。 设N是我们需要互连的节点集。我们想要构建图G的最小连通支配集,并且我们希望为N中的节点赋予优先级。 我们给每个节点u一个唯一的标识符id(u)。如果你在N中,我们让w(u)= 0,否则w(1)。 我们为每个节点u创建对(w(u),id(u))。

  • 每个节点u构建一个多集中继节点。也就是说,1跳邻居的集合M(u)使得每个2跳邻居是M(u)中的至少一个节点的邻居。 [最小M(u),解决方案越好]。

  • 当且仅在以下情况下,你在V'中: 你的所有邻居中都有最小的对(w(u),id(u))。 或者在M(v)中选择u,其中v是具有最小(w(u),id(u))的u的1跳邻居。

- 以集中方式执行此算法时的技巧是在计算2跳邻居时有效。我可以从O(n ^ 3)得到的最好的是通过矩阵乘法得到O(n ^ 2.37)。

- 我真的想知道最后一个解决方案的近似比例是什么。

我喜欢这个steiner树启发式的参考: 施泰纳树问题,黄禹兰; Richards Dana 1955- Winter Pawel 1952

答案 3 :(得分:1)

您可以尝试执行以下操作:

  1. 为所需的节点N创建minimal vertex-cover

  2. 将这些可能未连接的子图折叠到“大”节点中。也就是说,对于每个子图,将其从图中删除,并将其替换为新节点。调用这组节点N'

  3. N'中执行节点的最小顶点覆盖。

  4. “解压缩”N'中的节点。

  5. 不确定它是否在某个特定范围内给出近似值。你甚至可以欺骗算法做出一些非常愚蠢的决定。