我有一个未加权的连接图。我想找到一个连接的子图,它肯定包含一组特定的节点,并且尽可能少的附加内容。怎么能实现呢?
为了以防万一,我将使用更精确的语言重述问题。设G(V,E)为未加权,无向连通图。设N是V的某个子集。找到G(V,E)的最小连通子G'(V',E')的最佳方法是什么,这样N是V'的子集?
近似值很好。
答案 0 :(得分:9)
这正是众所周知的NP难Steiner Tree问题。如果没有关于实例的详细信息,很难就适当的算法提供建议。
答案 1 :(得分:5)
我无法想到找到最佳解决方案的有效算法,但假设您的输入图形密集,以下内容可能效果不错:
将输入图G(V, E)
转换为加权图G'(N, D)
,其中N
是要覆盖的顶点子集,D
是距离(路径)原始图中相应顶点之间的长度)。这将“折叠”您不需要的所有顶点到边缘。
计算G'
。
通过以下过程“展开”最小生成树:对于最小生成树中的每个边d
,采用图G
中的相应路径并添加所有顶点(包括端点) )在结果集V'
的路径上以及结果集E'
的路径中的所有边。
此算法很容易绊倒以提供次优解决方案。示例案例:等边三角形,其中在拐角处,在边的中点和三角形的中间存在顶点,并且沿着边的边缘以及从角的边缘到三角形的中间。为了覆盖角落,它足以选择三角形的单个中点,但是这个算法可能会选择边。尽管如此,如果图表密集,它应该可以正常工作。
答案 2 :(得分:3)
最简单的解决方案如下:
a)基于mst:
- 最初,V的所有节点都在V'
- 构建图G(V,E)的最小生成树 - 称之为T.
- loop:对于不在N中的T中的每个叶v,从V'中删除v
- 重复循环,直到T中的所有叶子都在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)
您可以尝试执行以下操作:
为所需的节点N
创建minimal vertex-cover。
将这些可能未连接的子图折叠到“大”节点中。也就是说,对于每个子图,将其从图中删除,并将其替换为新节点。调用这组节点N'
。
在N'
中执行节点的最小顶点覆盖。
“解压缩”N'
中的节点。
不确定它是否在某个特定范围内给出近似值。你甚至可以欺骗算法做出一些非常愚蠢的决定。