algorithm - 一种从图中获取所有连通子图的算法,它是否正确?

标签 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

最佳答案

这是我认为是您的原始算法的 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 位于禁止集中,因此无法再次使用。

因此,从表面的分析来看,该算法显得高效且正确。

关于algorithm - 一种从图中获取所有连通子图的算法,它是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18837026/

相关文章:

algorithm - DAG 中多个节点的最小公共(public)祖先

java - 区间交集

python - 通过随机嵌套数据进行最快搜索

database - 我可以使用优雅的配对功能作为数据库中的主键吗?

algorithm - 删除图中不必要的节点

c# - 如何连接点和吸收动量?

java - 如何检测数据的 "likeness"

algorithm - while(n>0) 和 while(n!=0) 求值的区别

c++ - 对 SPOJ 上的 POUR1 有什么建议?

algorithm - 与 15 拼图的 A-Star 曼哈顿启发式相比,线性冲突启发式是否会导致创建和探索更多节点?