断开图中的所有顶点 - 算法

Posted

技术标签:

【中文标题】断开图中的所有顶点 - 算法【英文标题】:Disconnect all vertices in a graph - Algorithm 【发布时间】:2015-09-09 05:44:19 【问题描述】:

我正在寻找一种算法,它可以找到顶点的最小子集,这样通过从图中删除这个子集(以及连接这些顶点的边),所有其他顶点都变得不连接(即,图不会有任何边)。

有这样的算法吗? 如果不是:您能否推荐某种启发式方法来指定顶点。

我对图论有基本的了解,如有不妥之处请见谅。

【问题讨论】:

要求我们推荐或查找书籍、工具、软件库、教程或其他场外资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,请描述问题以及迄今为止为解决该问题所做的工作。 @cybermonkey 没有这样的推荐请求。这个问题是主题,并且有一个明确的答案(参见@AmiTavory's)。 (显然有更多的答案,但没有一个会是自以为是的答案的垃圾邮件)。他正在描述一个问题,他正在得到一个答案。 @amit 它要求一个算法,这与'code for me'相同。 @cybermonkey 不,不是。要求算法是非常好的。 Example 1、Example 2、Example 3、Example 4。询问“如何做 X”是完全可以的,并且询问算法也是一个话题,因为它可以很容易地翻译成任何编程语言。您可以争辩说这个问题没有显示出足够的研究努力 - 但这是另一个问题。 【参考方案1】:

IIUC,这是经典的Minimum Vertex Cover 问题,不幸的是,NP Complete。

幸运的是,most intuitive and greedy possible algorithm 在这种情况下表现得非常好。

【讨论】:

当1.2738^(subset_size) time 太长时,“最直观和最贪婪的算法”只有“尽可能好”。​ ​【参考方案2】:

贪心算法是顶点覆盖的 2 近似值,理论上,根据唯一游戏猜想,它已经达到了最好的水平。在实践中,将顶点覆盖公式求解为整数程序很可能会产生更好的结果。该程序是

min sum_v in V x(v)
s.t.
forall u, v in E, x(u) + x(v) >= 1
forall v in V, x(v) in 0, 1.

【讨论】:

【参考方案3】:

试试这个方法:

定义一个变量来统计顶点数,从0开始; 创建一个顶点的最大堆,按每个顶点的相邻列表的长度排序; 从Heap的第一个顶点(边数最多的那个)中删除所有边并将其从Heap中删除,计数加1;

现在重新排序堆,因为顶点的边数发生了变化,重复上一步,直到从第一个顶点开始的相邻列表的长度为 0;

Heap Q
int count = 0

while(1)

    Q = Create_Heap(G)
    Vertex first = Q.pop
    if(first.adjacents.size() == 0) 
        break
    

    for( Vertex v : first.adjacent )
        RemoveEdge(first, v)
        RemoveEdge(v, first)    /* depends on the implementation */
    

    count = count + 1



return count

【讨论】:

以上是关于断开图中的所有顶点 - 算法的主要内容,如果未能解决你的问题,请参考以下文章

关于图中两个顶点间的路径问题

用Dijkstra算法求图中从顶点a到其他各顶点间的最短路径,并写出执行算法过程中各步的状态。

在给定起始顶点和深度限制的循环定向图中寻找所有可能的路径。

求高手给个遍历算法

常用的图算法:深度优先(DFS)

用邻接表表示图进行深度优先遍历时,通常采用()来实现算法