在python中使用元组的元组列表查找路径

时间:2019-04-17 14:12:46

标签: python recursion graph-theory

我有一个这样的元组列表。我想获取从源到目的地的所有路径。例如,我的来源是1,目的地是5。那么((1, 3), [5, 45, 86, 3]), ((3, 7), [16, 187, 48, 4]), ((7, 9), [31, 111, 63, 59]), ((9, 5), [78, 14, 53, 6])是一条路径。

[((1, 3), [5, 45, 86, 3]), ((7, 2), [62, 122, 23, 9]), ((5, 8), [98, 137, 52, 31]), ((8, 7), [82, 194, 66, 23]), ((4, 0), [93, 161, 49, 29]), ((6, 9), [12, 40, 51, 23]), ((6, 5), [87, 22, 89, 10]), ((0, 9), [24, 190, 57, 28]), ((1, 0), [32, 45, 100, 29]), ((3, 7), [16, 187, 48, 4]), ((10, 4), [30, 157, 85, 49]), ((9, 10), [46, 58, 100, 48]), ((9, 7), [22, 66, 61, 24]), ((6, 4), [81, 16, 78, 3]), ((2, 0), [73, 124, 35, 6]), ((6, 10), [71, 2, 61, 24]), ((9, 1), [88, 177, 30, 19]), ((9, 7), [20, 2, 44, 27]), ((10, 7), [54, 177, 92, 30]), ((4, 7), [57, 143, 83, 68]), ((1, 8), [90, 190, 96, 8]), ((3, 8), [77, 56, 84, 62]), ((3, 6), [55, 135, 75, 64]), ((4, 3), [76, 4, 69, 64]), ((0, 6), [16, 39, 82, 27]), ((8, 9), [38, 1, 17, 4]), ((2, 0), [97, 108, 84, 2]), ((8, 3), [37, 200, 31, 13]), ((1, 9), [42, 5, 65, 35]), ((5, 0), [52, 65, 60, 31]), ((1, 0), [40, 18, 38, 2]), ((3, 9), [70, 8, 99, 52]), ((0, 8), [79, 184, 98, 68]), ((7, 9), [31, 111, 63, 59]), ((9, 2), [99, 187, 50, 17]), ((4, 9), [4, 25, 67, 52]), ((9, 5), [78, 14, 53, 6]), ((8, 1), [13, 66, 60, 35]), ((3, 10), [78, 200, 38, 9]), ((6, 9), [46, 7, 95, 54]), ((1, 8), [86, 84, 42, 2]), ((10, 5), [76, 88, 27, 22]), ((2, 3), [3, 143, 90, 70]), ((10, 0), [39, 160, 48, 45]), ((10, 1), [99, 8, 73, 14])]

我已经尝试过递归解决这个问题。我得到edge的第一个元素,并检查它是否是源。如果是,那么我检查第二个元素是目的地。如果是,我返回路径。如果不是,请递归检查所有选项。

def findpath(s,d):
    path = []
    for n in graph:
        e = n[0]
        w_list = n[1]
        if e[0] == s:
            if e[1] == d:
                path.append(e)
                #print(e)
            else:
                pah = findpath2(e[1],d)
                path.append(pah)
    return path
def findpath2(f,d):
    path2 = []
    for n in graph:
        e = n[0]
        w_list = n[1]
        if e[0] == f:
            if e[1] == d:
                path2.append(e)
                break
                #print(e)
            else:
               findpath2(e[1],d)

s= 1
d = 5
path = findpath(s,d)
print(path)

[(1, 3),(3, 7),(7, 9),(9, 5)]之类的。但我收到此错误。比较中超过了最大递归深度

1 个答案:

答案 0 :(得分:0)

如果您不需要体重清单,只需使用networkx

import networkx as nx

# You didn't write your graph object, so it is the dummy random graph
graph = [
    [(0,1),[1,2,3,4,5]],
    [(2,3),[1,2,3,4,5]],
    [(1,3),[1,2,3,4,5]],
    [(1,2),[1,2,3,4,5]],
    [(3,4),[1,2,3,4,5]],
    [(0,5),[1,2,3,4,5]],
    [(5,6),[1,2,3,4,5]],
    [(4,6),[1,2,3,4,5]],
    [(2,6),[1,2,3,4,5]],
]

G = nx.DiGraph()
G.add_edges_from(e[0] for e in graph)
list(nx.all_simple_paths(G, 1, 6))

返回所有简单路径:

[[1, 2, 3, 4, 6], [1, 2, 6], [1, 3, 4, 6]]

对于这样的问题,递归非常不好,因为您将陷入最大调用堆栈值(〜50-100)中。每个非小图都会迫使您的脚本崩溃。