2012-01-18 64 views
8
for a in map: 
    for b in map[a]: 
     for c in map[b]: 
      for d in map[c]: 
       for e in map[d]: 
        print a+b+c+d+e 

上面的代码用于在图中创建一定长度的所有路径。 map [a]表示您可以从点a到达的点。更好的等效于这个疯狂的嵌套python循环

我怎样才能改变它来模拟有任意数量的循环?

这就像一个笛卡尔积(itertools.product),其中每次迭代 您对下一个元素的选择仅限于map [current_point]中的那些元素。

+2

那么,你有递归标记吧..你尝试了吗? – wim 2012-01-18 07:11:55

回答

6
map = { 
    'a': ['b', 'c'], 
    'b': ['c', 'd'], 
    'c': ['d', 'a'], 
    'd': [] 
} 

def print_paths(map, start, length, prefix = ''): 
    if length == 0: 
     print prefix 
    else: 
     for a in map[start]: 
      print_paths(map, a, length - 1, prefix + start) 

for a in map.keys(): 
    print_paths(map, a, 5) 
+1

对不起,我忘了提到地图[a] [b]是一个整数,表示a到b之间的距离。所以你的解决方案一旦达到整数就停止工作。你能告诉我如何改变它到嵌套循环的确切等价物吗?所以这个功能不会超越地图[a]。 (对于任何给定的点X,映射[X]是足够的,因为你选择某个点可以下一步的位置并不取决于你如何到达那里) – Babak 2012-01-18 07:42:12

+0

如果map [a] [b]是一个整数,代码无法工作。你能用一个'map'的实例来更新这个问题吗?我会添加我认为这个答案的那种'map'。 – 2012-01-18 16:42:38

+0

...并编辑实际工作的答案,因为我和5个上级都没有注意到它没有...... – 2012-01-18 16:52:35

3

这是一个经典的递归问题。您的函数应该返回每个子节点的结果与所有函数结果的结果值的串联。正如你可以看到一句话,函数的行为在递归的方式解释说:

myGraph = { 1:[2,3], 2:[3,4] } 

def recorre(node_list, p = ''):  
    for node in node_list: 
     if node in myGraph and myGraph[node]: 
      recorre(myGraph[node], p+unicode(node)) 
     else: 
      print p+unicode(node) 

recorre(myGraph) 

结果:

>>> recorre(myGraph) 
123 
124 
13 
23 
24 

此代码是一个起点。您可以将所有路径存储在列表中,使用yield发生器等。不要忘记防止出现圆圈。

另外,请看igraph solution。当然这个库可以帮助你,看到这个例子:Finds all shortest paths (geodesics) from a vertex to all other vertices

问候。

1

就像其他的建议,使用递归:

distances = []   

    def compute_distance(map, depth, sum): 
     if depth == 0 or len(map) == 0: 
      distances.append[sum] 
     else: 
      for a in map: 
       compute_distance(map[a], depth - 1, sum + a) 

    compute_distance(map, x, 0)