Почему алгоритм Дейкстры не работает для графов с отрицательными ребрами?

Условно есть такой граф, введите сюда описание изображения.

Вот код поиска кратчайшего пути по алгоритму Дейкстры. `

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 и считает его кратчайшим и не перепроверяет прошлые пути, а также считает любое увеличение кол-ва ребер за увеличение веса всего пути, но отрицательные числа нарушают этот принцип. Надеюсь этот ответ будет полезен.

→ Ссылка