Проблема с отрицательным преимуществом заключается в том, что вы можете перемещаться по нему столько раз, сколько захотите.
Если вы вводите правило, что преимущество не может использоваться более одного раза, у вас все еще есть проблема.Алгоритм Дейкстры включает в себя маркировку узла как «посещенного», когда его расстояние от начального узла считается известным раз и навсегда.Это происходит до того, как все края были изучены;кратчайший путь от начального узла к узлу X найден, все остальные пути от начального узла уже длиннее этого, ничто из обнаруженного позже не сможет сделать эти пути короче .Но если где-то есть ребра с отрицательной стоимостью, то позднее открытие может сделать путь короче, поэтому может случиться так, что существует более короткий путь, который Дейкстра не обнаружит.
Если толькоРебра, которые соединяются с начальным узлом, могут иметь отрицательные затраты, тогда у вас все еще есть проблема, потому что кратчайший путь может включать повторное посещение начального узла, чтобы воспользоваться преимуществами отрицательных затрат, что Дейкстра не может сделать.
Если вы навязываете другое правило, что узел не может быть посещен более одного раза, тогда алгоритм Дейкстры работает.Обратите внимание, что в алгоритме Дейкстры начальному узлу дается начальное расстояние ноль.Если вы дадите ему другое начальное расстояние, алгоритм все равно найдет кратчайший путь - но все расстояния будут отклонены на ту же величину.(Если вы хотите получить реальное расстояние в конце, вы должны вычесть введенное вами значение.)
- Итак, возьмите свой график, назовите его A , найдите наименьшую стоимостьлюбое ребро, соединенное с начальным узлом, назовите его k, что в этом случае будет отрицательным).
- Создайте новый график B , который вы получите, вычтя k из стоимости каждого ребра, соединенного с начальным узлом.Обратите внимание, что все эти затраты теперь неотрицательны.Так Дейкстра работает на B .Также обратите внимание, что кратчайший путь в B также является кратчайшим путем в A .
- Назначьте начальному узлу B расстояние k, затем запустите Dijkstra (это даст тот же путь, что и бег с начальным расстоянием, равным нулю).Сравните это с наивным запуском Dijkstra на A : как только вы покидаете начальный узел , на двух графиках все одинаково.Расстояния одинаковы, решения одинаковы, оба будут давать один и тот же путь.А в случае A расстояние будет правильным, так как оно началось с нуля.