2012-04-28 2 views
2

В python У меня есть график как представление списка смежности. и расстояние от конкретных точек до всех остальных элементов графика.backtracking на графике

graph = { 
    1 :[2, 7], 
    2 :[1, 3], 
    3 :[2, 4, 8], 
    4 :[3, 5, 9], 
    5 :[4, 6, 9], 
    6 :[5, 8, 10], 
    7 :[1, 8,10], 
    8 :[3, 6, 7, 9], 
    9 :[4, 5, 8], 
    10:[7, 6] 
    } 

distance = {1: 1, 2: 0, 3: 0, 4: 1, 5: 2, 6: 2, 7: 2, 8: 1, 9: 2, 10: 3} 

Как я могу отступиться путь от элемента: к примеру, если я буду пытаться вернуться назад с 10, он должен вернуть:

[10, 7, 1, 2] 
[10, 7, 8, 3] 
[10, 6, 8, 3] 

Я пытался сделать это рекурсивно

def findprev(graph, distance, el, path = []): 
    value = distance[el] 
    if value == 0: 
     print path 
     path = [] 

    for i in graph[el]: 
     if value - 1 == distance[i]: 
      path.append(i) 
      path = findprev(graph, distance, i, path) 
    return path 

, но, по-видимому, я теряю что-то важное, потому что результат:

[7, 1, 2] 
[8, 3] 
[6, 8, 3] 

Может кто-нибудь поможет найти ошибку

+3

Это не так много «откат» (в том смысле, компьютерные науки) так, как это нахождение пути между двумя узлами в графе через поиск (например, DFS, BFS). – ninjagecko

+1

http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument –

ответ

1
def findprev(graph, distance, el, path=None): 
    if path is None: 
     path = [el] 
    else: 
     path.append(el) 
    value = distance[el] 
    if value == 0: 
     print(path) 

    for i in graph[el]: 
     if value - 1 == distance[i]: 
      findprev(graph, distance, i, path[:]) 

findprev(graph, distance, 10) 

Выход:

[10, 7, 1, 2] 
[10, 7, 8, 3] 
[10, 6, 8, 3] 

Или, если вы хотите возвратить полученные пути:

def findprev(graph, distance, el, path=None): 
    if path is None: 
     path = [el] 
    else: 
     path.append(el) 
    value = distance[el] 
    if value == 0: 
     return [path] 

    result = [] 
    for i in graph[el]: 
     if value - 1 == distance[i]: 
      paths = findprev(graph, distance, i, path[:]) 
      for p in paths: 
       result.append(p) 
    return result 
+0

Если вы просто передаете простой «путь», вы повторно используете один и тот же список для построения разных путей. Если вы передадите 'путь [:]', то вместо этого будет передан экземпляр рекурсивного вызова. –

+0

Также никогда не используйте изменяемые значения в качестве аргументов по умолчанию для функции. См .: http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument –

1

Вот другое решение твоя проблема. Я переименовал distance в distances, потому что это показалось мне лучшим именем, и я использую имя distance для расстояния каждой отдельной точки.

>>> def find_paths(point,path=[]): 
     distance = distances[point] 
     elements = graph[point] 
     if distance == 0: 
      yield path + [point] 
     else: 
      for element in elements: 
       if distances[element] == distance - 1: 
        for item in find_paths(element,path+[point]): 
         yield item 


>>> for path in find_paths(10): 
     print path 


[10, 7, 1, 2] 
[10, 7, 8, 3] 
[10, 6, 8, 3]