#python #graph #graph-theory
#python #График #теория графов
Вопрос:
Я пытаюсь найти кратчайший путь на взвешенном графике, учитывая ограничение, что путь должен иметь общее расстояние меньше некоторого параметра (скажем, 1000).
Я попробовал следующее, но я не знаю, почему мой код неправильный.
def directedDFS(digraph, start, end, maxTotalDist):
visited = []
if not (digraph.hasNode(start) and digraph.hasNode(end)):
raise ValueError('Start or end not in graph.')
path = [str(start)]
if start == end:
return path
shortest = None
for node in digraph.childrenOf(start):
if (str(node) not in visited):
visited = visited [str(node)]
firststep_distance = digraph.childrenOf(start)[node][0]
firststep_outer_distance = digraph.childrenOf(start)[node][1]
if (firststep_distance <= maxTotalDist):
newPath = directedDFS(digraph, node, end, maxTotalDist-firststep_distance)
if newPath == None:
continue
if (shortest == None or TotalDistance(digraph,newPath) < TotalDistance(digraph,shortest)):
shortest = newPath
if shortest != None:
path = path shortest
else:
path = None
return path
Другое дело, что я не хочу сравнивать на основе расстояния пути, начинающегося с данного узла, но на основе расстояния ВСЕГО ПУТИ от исходной начальной точки. Хотя я не знаю лучшего способа сделать это здесь.
Комментарии:
1. Вы имеете в виду кратчайший с точки зрения количества переходов или расстояния (последнее тривиально, поэтому я предполагаю, что это первое)?
2. Вы пытаетесь найти путь, содержащий наименьшее количество ребер, где общая стоимость пути (сумма весов его ребер) меньше 1000?
Ответ №1:
Я действительно не могу разобраться в предоставленном вами коде ( firststep_distance
? firststep_outer_distance
?). Не могли бы вы указать название алгоритма, который вы пытаетесь реализовать?
Если вы просто что-то придумываете на лету, и вы не ставите перед собой цель заново изобрести теорию графов для образовательных целей, я бы посоветовал поискать стандартный алгоритм кратчайшего пути. Если вы можете гарантировать, что ваши веса неотрицательны, то стандартом является алгоритм Дейкстры. Википедия сообщит об улучшенной асимптотической среде выполнения, если вы подкрепите ее кучей Фибоначчи, но не попадайтесь в эту ловушку — по-видимому, кучи Фибоначчи имеют ужасную производительность на практике.
Если Дейкстры недостаточно, взгляните на A*-search
методы. Здесь, как и во всех вопросах алгоритма, CLR — ваш лучший гид, но Википедия чертовски близко. Надеюсь, это поможет!
Ответ №2:
Я также не могу точно сказать, что происходит, без дополнительного кода или информации, но это касается:
if (firststep_distance <= maxTotalDist):
newPath = directedDFS(digraph, node, end, maxTotalDist-firststep_distance)
Если вы уменьшаете maxTotalDistance при каждом рекурсивном вызове, то firststep_distance (который, я полагаю, является весом пути) должен быть больше оставшегося расстояния, а не меньше.
Комментарии:
1. Нет, firststep_distance — это вес первого шага в пути. Я должен был прояснить это.
2. Я оговорился, под весом пути я подразумеваю вес ребра от начала до узла.