从图中获取所有连接子图的算法是否正确?

时间:2013-09-16 20:47:04

标签: algorithm graph-algorithm

我试图找到一个快速算法,以获得所有连接的子图形成一个子图长度受限的无向图。简单的方法,例如来自每个顶点的BFS或DFS会产生大量的等于子图,因此在每次算法迭代中我们都必须修剪子图集。我在俄罗斯数学论坛an algorithm找到了:

Procedure F(X,Y)
//X set of included vertices 
//Y set of forbidden vertices to construct new subgraph
1.if |X|=k, then return;
2.construct a set T[X] of vertices that adjacent to vertices from X (If X is a empty set, than T[X]=V), but not belong to the sets X,Y;
3.Y1=Y;
4.Foreach v from T[X] do:
__4.1.X1=X+v;
__4.2.show subgraph X1;
__4.3.F(X1,Y1);
__4.4.Y1=Y1+v;

Initial call F(X,Y):
X, Y = empty set;
F(X,Y); 

这个算法的主要思想是使用“禁止集”,因此,这个不需要修剪,这个算法的作者说它比基于修剪等于子图的解决方案快300倍。但我没有找到任何证据证明这个算法是正确的。

更新: 找到了更有效的解决方案here

2 个答案:

答案 0 :(得分:2)

以下是我认为是您原始算法的Python实现:

from collections import defaultdict

D=defaultdict(list)
def addedge(a,b):
    D[a].append(b)
    D[b].append(a)

addedge(1,2)
addedge(2,3)
addedge(3,4)

V=D.keys()
k=2

def F(X,Y):
    if len(X)==k:
        return
    if X:
        T = set(a for x in X for a in D[x] if a not in Y and a not in X)
    else:
        T = V
    Y1=set(Y)
    for v in T:
        X.add(v)
        print X
        F(X,Y1)
        X.remove(v)
        Y1.add(v)

print 'original method'
F(set(),set())

F生成大小为< = k的所有连通子图,其中子图必须包含X中的顶点(连接的子图本身),并且不得在Y中包含顶点。

我们知道要在子图中包含另一个顶点,我们必须使用连接的顶点,这样我们就可以根据最终子图内的第一个连接顶点v的标识进行递归。禁止集意味着我们确保无法生成子图的第二个副本,因为此副本必须使用v,但v在禁用集中,因此不能再次使用。

因此,在这种肤浅的分析水平上,这种算法看似高效且正确。

答案 1 :(得分:0)

您没有很好地描述算法。我们不知道k是这个算法中的V是什么或者是什么。我只假设k是子图上的受限长度,V是某个根顶点。

如果这是真的,那么我认为这个算法不正确。假设我们有一个只有两个连接顶点v1,v2和受限制的子图k = 1的图。

在第一次迭代中:X,Y =空,T(X)= {v1},X1 = {V1},Y1 =空,我们显示X1。

  • 然后我们递归调用F(X1,Y1),它应该立即返回,因为| X | = | {v1} | = 1

现在回到第一次迭代Y(1)= v1。循环结束,初始调用也在这里结束。所以我们只打印出X1。我们打算打印出X1,X2。

顺便说一句,不要“测试”算法 - 没有办法测试它(可能的测试用例的数量是无限的)。你确实应该正式证明它。