Почему алгоритм Дейкстры не работает для графов с отрицательными ребрами?
Вот код поиска кратчайшего пути по алгоритму Дейкстры. `
def find_lowest_cost_node(costs):
lowest_cost = float("inf")
lowest_cost_node = None
for node in costs:
cost = costs[node]
if (cost < lowest_cost) and (node not in processed):
lowest_cost = cost
lowest_cost_node = node
return lowest_cost_node
graph = {}
graph["Start"] = {}
graph["Start"]["a"] = 5
graph["Start"]["b"] = 0
graph["a"] = {}
graph["a"]["b"] = -7
graph["b"] = {}
graph["b"]["fin"] = 35
graph["fin"] = {}
costs = {}
costs["a"] = 5
costs["b"] = 0
costs["fin"] = float("inf")
parents = {}
parents["a"] = "Start"
parents["b"] = "Start"
parents["fin"] = None
processed = []
node = find_lowest_cost_node(costs)
while node is not None:
cost = costs[node]
neighborts = graph[node]
for n in neighborts.keys():
new_cost = cost + neighborts[n]
if costs[n] > new_cost:
costs[n] = new_cost
parents[n] = node
processed.append(node)
node = find_lowest_cost_node(costs)
print(costs["fin"])
print(parents)
`
Я так полагаю, что по идеи алгоритма, стоимость fin - равняется 35, т.к узел C был выбран первым, после чего был обработан узел D, где в хеш таблице costs по ключу fin было записано 35. Следующим узлом был выбран B, где мы обновили стоимость С, но не D. Поэтому стоимость D по прежнему осталась 35. Но мы же обновили родителя для узла C, и в итоге получилось вот так
.
И на сколько я понимаю, мы можем правильно восстановить по таблице родителей стоимость? Или я где-то что-то путаю?
Ответы (1 шт):
Я видел этот пример в книге "Грокаем алгоритмы" Адитьи Бхаргавы (см. главу "Алгоритм Дейкстры", часть "Ребра с отрицательным весом"). Дело в том, что алгоритм Дейкстры находит путь от узла A до узла B и считает его кратчайшим и не перепроверяет прошлые пути, а также считает любое увеличение кол-ва ребер за увеличение веса всего пути, но отрицательные числа нарушают этот принцип. Надеюсь этот ответ будет полезен.
