问题描述
我在网上看到了 Johnson 算法的代码,但很难将其转换为一个函数,该函数接受 2 个参数(列表和起始节点),该函数返回有向图中最长的循环。我见过一个使用 networkx (Finding the longest cycle in a directed graph using DFS) 的代码(第三个答案),但我不知道如何在不使用 networkx 的情况下做到这一点。
我还搜索了 networkx 的 simple_cycle 函数的源代码,该函数使用 Johnson 算法,但无法将其转换为我需要的函数,因为内部使用了一些 networkx 函数,而有些函数没有返回语句。 (https://networkx.org/documentation/stable//_modules/networkx/algorithms/cycles.html)
#source code for networkx's simple_cycle function (most comments removed)
def simple_cycles(G):
def _unblock(thisnode,blocked,B):
stack = {thisnode}
while stack:
node = stack.pop()
if node in blocked:
blocked.remove(node)
stack.update(B[node])
B[node].clear()
for v in subG:
if subG.has_edge(v,v):
yield [v]
subG.remove_edge(v,v)
while sccs:
scc = sccs.pop()
sccG = subG.subgraph(scc)
startnode = scc.pop()
path = [startnode]
blocked = set() # vertex: blocked from search?
closed = set() # nodes involved in a cycle
blocked.add(startnode)
B = defaultdict(set) # graph portions that yield no elementary circuit
stack = [(startnode,list(sccG[startnode]))] # sccG gives comp nbrs
while stack:
thisnode,nbrs = stack[-1]
if nbrs:
nextnode = nbrs.pop()
if nextnode == startnode:
yield path[:]
closed.update(path)
elif nextnode not in blocked:
path.append(nextnode)
stack.append((nextnode,list(sccG[nextnode])))
closed.discard(nextnode)
blocked.add(nextnode)
continue
if not nbrs: # no more nbrs
if thisnode in closed:
_unblock(thisnode,B)
else:
for nbr in sccG[thisnode]:
if thisnode not in B[nbr]:
B[nbr].add(thisnode)
stack.pop()
path.pop()
H = subG.subgraph(scc) # make smaller to avoid work in SCC routine
sccs.extend(scc for scc in nx.strongly_connected_components(H) if len(scc) > 1)
需要帮助:一个python函数,它返回给定节点的有向图中最长的循环。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)