给定图G,节点n和长度L,我想收集长度为L的所有(非循环)路径离开n。
你对如何处理这个有什么想法吗?
到目前为止,我的图表是一个networkx.Graph实例,但我并不关心igraph被推荐。
非常感谢!
答案 0 :(得分:5)
接近(并完全解决)此问题的一种非常简单的方法是使用图的邻接矩阵 A 。 A ^ L 的(i,j)元素是节点 i 和 j 之间的路径数长度 L 。因此,如果您对所有 j 总结 i 并将其固定在 n ,那么您将获得从节点 n 发出的所有路径长度 L 。
这也很遗憾地计算循环路径。幸运的是,这些可以从元素A^L(n,n)
中找到,所以只需减去它。
所以你的最终答案是: Σj{A^L(n,j)} - A^L(n,n)
。
谨慎提醒:假设您正在寻找节点1中长度为5的路径:此计算还将计算内部小周期的路径,如1-2-3-2-4
,其长度为5或4,具体取决于您的选择方式看到它,所以要小心。
答案 1 :(得分:2)
我想扩展Lance Helsten的优秀答案:
深度限制搜索搜索特定深度内的特定节点(您称之为长度L),并在找到它时停止。如果您将在他的答案中查看wiki link中的伪代码,您将理解这一点:
DLS(node, goal, depth) {
if ( depth >= 0 ) {
if ( node == goal )
return node
for each child in expand(node)
DLS(child, goal, depth-1)
}
}
但是,在您的情况下,当您从节点中寻找长度为L的所有路径时,您将无法在任何地方停留。因此必须将伪代码修改为:
DLS(node, depth) {
for each child in expand(node) {
record paths as [node, child]
DLS(child, depth-1)
}
}
完成记录DLS连续巢穴中的所有单链路路径后,只需获取它们的产品即可获得整个路径。这些数量为您提供从节点开始所需深度的路径数。
答案 2 :(得分:1)
使用深度限制搜索(http://en.wikipedia.org/wiki/Depth-limited_search),您可以在其中保留一组访问节点,以便在路径上检测周期。例如,您可以从节点n构建一个树,其中所有节点和长度为L,然后修剪树。
我快速搜索图算法来做到这一点,但没有找到任何东西。有一个图表算法列表(http://en.wikipedia.org/wiki/Category:Graph_algorithms)可能正是您正在寻找的。 p>
答案 3 :(得分:1)
此解决方案可能在效率方面有所改进,但似乎非常短,并且使用了networkx功能:
G = nx.complete_graph(4)
n = 0
L = 3
result = []
for paths in (nx.all_simple_paths(G, n, target, L) for target in G.nodes_iter()):
print(paths)
result+=paths
答案 4 :(得分:1)
这是我在阅读答案后想出的另一个(相当幼稚)的实现:
def findAllPaths(node, childrenFn, depth, _depth=0, _parents={}):
if _depth == depth - 1:
# path found with desired length, create path and stop traversing
path = []
parent = node
for i in xrange(depth):
path.insert(0, parent)
if not parent in _parents:
continue
parent = _parents[parent]
if parent in path:
return # this path is cyclic, forget
yield path
return
for nb in childrenFn(node):
_parents[nb] = node # keep track of where we came from
for p in findAllPaths(nb, childrenFn, depth, _depth + 1, _parents):
yield p
graph = {
0: [1, 2],
1: [4, 5],
2: [3, 10],
3: [8, 9],
4: [6],
5: [6],
6: [7],
7: [],
8: [],
9: [],
10: [2] # cycle
}
for p in findAllPaths(0, lambda n: graph[n], depth=4):
print(p)
# [0, 1, 4, 6]
# [0, 1, 5, 6]
# [0, 2, 3, 8]
# [0, 2, 3, 9]