我需要一种算法来查找有向图中所有并行路径的集合。以下是我用于测试的示例的直观表示。
以下是我在Python中使用networkx的示例代码:
import networkx as nx
G = nx.MultiDiGraph()
# relevant part of graph to my question
G.add_edges_from([(1,2),(2,3),(3,4),(2,5),(5,6),(6,4),(4,7)])
# subordinate part of graph to my question
G.add_edges_from([(7,8),(8,9),(7,10),(10,11),(11,13),(11,12),(12,14)])
pp = get_parallel_paths(G) # -> the function I'm looking for
# pp should contain:
# pp = [[[(2,3),(3,4)],[(2,5),(5,6),(6,4)]],[...]]
# the procedure should list all sets of parallel paths
# hence the [...] indicates a possible other set of parallel paths (not in example)
我正在寻找的功能是“get_parallel_paths”。它不一定是在Python中:非常欢迎指向任何可以帮助我实现的算法的指针。
答案 0 :(得分:2)
如果考虑带分支的并行路径,则此问题将是NP完全的(参见vertex-disjoint paths problem)。
但是,由于不考虑分支,问题很简单:
伪码:
allParallelPaths = []
#loop over all vertices to find ones that split
foreach(vertices as v)
if(out-degree(v) > 1)
#store every eventual target and the paths that got there
destinations = new Map()
foreach(v.out as e)
path = [e]
#stop at any vertex that has non-one in- or out-degree
while(in-degree(e.target) == 1 && out-degree(e.target) == 1)
e = e.target.out[0]
path.push(e)
#make a list of paths that reached the destination
if(empty(destinations[e.target]))
destinations[e.target] = []
destinations[e.target].push(path)
foreach(destinations as dest)
if(dest.size > 1)
allParallelPaths.push(dest)
答案 1 :(得分:2)
有一个内置函数可列出两个顶点之间的所有简单路径。这用它来列出任意两个顶点之间的所有路径集:
def get_parallel_paths(G):
return [list(nx.all_simple_paths(G, i, j)) for i in G.nodes_iter() for j in G.nodes_iter() if i != j and nx.has_path(G, i, j)]
要过滤出内部顶点大于2的任何路径,我们可以这样做:
def get_parallel_paths(G):
colpaths = []
for i in G.nodes_iter():
for j in G.nodes_iter():
if i == j:
continue
nbp = nobranchpaths(G, i, j)
if len(nbp) > 1:
colpaths += [nbp]
return colpaths
def nobranchpaths(G, u, v):
paths = []
for p in nx.all_simple_paths(G, u, v):
if len(p) == 2 or max(G.degree(i) for i in p[1:-1]) == 2:
paths += [p]
return paths
这仅包括存在多个路径的顶点对;要包含具有唯一路径的对,请将if len(nbp) > 1:
更改为if len(nbp):