Ответ 1
Причина использования ключа уменьшения вместо повторной вставки узлов заключается в том, чтобы количество узлов в приоритетной очереди оставалось небольшим, и, таким образом, общее количество очередей приоритетной очереди было небольшим, а стоимость баланса каждой приоритетной очереди - низкой.
В реализации алгоритма Дейкстры, который повторно вставляет узлы в очередь приоритетов с их новыми приоритетами, один узел добавляется в очередь приоритетов для каждого из m ребер в графе. Это означает, что в очереди с приоритетами имеется m операций очереди и m операций очереди, что дает общее время выполнения O (m T e + m T d), где T e - время, необходимое для помещения в очередь с приоритетами, а T d - время, необходимое для удаления из очереди с приоритетами.
В реализации алгоритма Дейкстры, который поддерживает клавишу уменьшения, приоритетная очередь, содержащая узлы, начинается с n узлов в ней и на каждом шаге алгоритма удаляет один узел. Это означает, что общее количество удалений кучи равно n. Каждому узлу будет назначен ключ уменьшения, возможно, один раз для каждого входящего в него ребра, поэтому общее количество выполненных ключей уменьшения составляет не более m. Это дает время выполнения (n T e + n T d + m T k), где T k - необходимое время позвонить по понижению.
Так как это влияет на время выполнения? Это зависит от того, какую очередь приоритетов вы используете. Вот краткая таблица, показывающая различные очереди с приоритетами и общее время выполнения различных реализаций алгоритма Дейкстры:
Queue | T_e | T_d | T_k | w/o Dec-Key | w/Dec-Key
---------------+--------+--------+--------+-------------+---------------
Binary Heap |O(log N)|O(log N)|O(log N)| O(M log N) | O(M log N)
Binomial Heap |O(log N)|O(log N)|O(log N)| O(M log N) | O(M log N)
Fibonacci Heap | O(1) |O(log N)| O(1) | O(M log N) | O(M + N log N)
Как вы можете видеть, с большинством типов очередей с приоритетами на самом деле нет разницы в асимптотическом времени выполнения, и версия с уменьшением ключа вряд ли будет работать намного лучше. Однако если вы используете реализацию кучи Фибоначчи очереди с приоритетами, то алгоритм Дейкстры действительно будет более асимптотически более эффективным при использовании клавиши уменьшения.
Короче говоря, использование клавиши уменьшения и очереди с хорошим приоритетом может отбросить асимптотическое время выполнения Dijkstra сверх того, что возможно, если вы продолжаете выполнять постановки в очередь и удаления.
Помимо этого, некоторые более продвинутые алгоритмы, такие как алгоритм кратковременных путей Габова, используют алгоритм Дейкстры в качестве подпрограммы и в значительной степени полагаются на реализацию с уменьшением ключа. Они используют тот факт, что если вы заранее знаете диапазон допустимых расстояний, вы можете построить суперэффективную очередь с приоритетами на основе этого факта.
Надеюсь это поможет!