求有向图中以一个顶点V为起止点的所有简单回路(python)
作者:互联网
前言
参考链接https://www.cnblogs.com/zhaodongge/p/10680313.html
前段时间在做数学建模题目时遇到了航班任务环的问题,然后去网上查了相关的代码,发现有好几个的都是先找到一个简单路径,然后去结果集中查重,确定该路径不重复后才加入结果集。他的查重认为,回路0→1→2→3(→0)与回路2→3→1→0(→2)是两条相同的回路。个人感觉查重的机制不太适合我要解决的问题,随后就自己写了一个,这个方法还是借鉴了DFS的思想查找图中的简单回路。在DFS访问每一个顶点时,首先将它加入到一个路径暂存数组path中,其次将这个顶点的相邻点入栈,然后通过一个count=[]数组记录这个顶点的出度数,以保证图每个顶点的出度只被用过一次。由于时间有限,我也不好作过多的文字解释,想知道原理的请自行按照程序手动跑一跑,主要注意stack、path、count这三个数组的变化情况即可。希望能帮到大家!
例题:如下面的有向图,求出以A为起止点的所有简单回路(以B、C为起点同理)
具体代码如下:
#输入:图(邻接表形式)、对图进行DFS的起始顶点V_start
#输出:图中以V_start为起点的所有简单回路
def DFS(graph,startNode):
stack = []
stack.append(startNode)
path=[]#记录当前路径
ALL_Path=[]#所有路径的结果集
Path_Name=''#一条路径的名称
count=[1]#记录每个结点的出度,起始加入一个“1”防止第一次不执行
while (len(stack) > 0):
#若刚加入path数组的顶点V还有出度没有使用过,则进行如下操作
if count[-1]>0:
vertex = stack.pop()#访问顶点V的一个邻接顶点M,相当于使用用了一次顶点V的某一个出度
count[-1]-=1#将顶点V的未使用出度的个数减1
#若找到一条回路,则将该回路保存至ALL_Path
if vertex==startNode and len(path)!=0:
for i in path:
Path_Name+=(i+'→')
Path_Name+=startNode
ALL_Path.append(Path_Name)
Path_Name=''
#若被访问顶点M不在当前路径中,则将M加入到路径数组path中,然后将M的邻接顶点入栈、统计M的出度个数加在count数组的后面
elif vertex not in path:
path.append(vertex)
nodes = graph[vertex]
count.append(len(nodes))
for w in nodes:
stack.append(w)
#若刚加入path数组的顶点V的所有出度均使用过,则把顶点V从path数组中移出,相当于进行一个回溯
else:
count.pop()
path.pop()
#打印以V_start为起点的所有简单回路
for i in ALL_Path:
print(i)
if __name__=="__main__":
a={ 'A':['B','C'],
'B':['A','C'],
'C':['A','B'],
}
V_start='A'
DFS(a,V_start)
运行结果如下:
标签:中以,count,有向图,回路,起止点,Path,path,stack,顶点 来源: https://blog.csdn.net/weixin_47082836/article/details/121049650