노드를 다시 삽입하는 대신 감소 키를 사용하는 이유는 우선 순위 대기열의 노드 수를 작게 유지하여 우선 순위 대기열에서 빼는 총 수를 줄이고 각 우선 순위 대기열 균형의 비용을 낮게 유지하기 위해서입니다.
노드를 새로운 우선 순위로 우선 순위 대기열에 다시 삽입하는 Dijkstra 알고리즘의 구현에서 그래프의 m 개 에지 각각에 대한 우선 순위 대기열에 하나의 노드가 추가됩니다. 즉, 우선 순위 대기열에는 m 개의 대기열에 넣기 작업과 m 개의 대기열에서 빼기 작업이있어 총 런타임이 O (m T e + m T d )가됩니다. 여기서 T e 는 우선 순위 대기열에 추가하는 데 필요한 시간이고 T d 는 우선 순위 대기열에서 대기열을 빼는 데 필요한 시간입니다.
감소 키를 지원하는 Dijkstra의 알고리즘 구현에서 노드를 보유하는 우선 순위 대기열은 n 개의 노드로 시작하고 알고리즘의 각 단계에서 하나의 노드를 제거합니다. 이는 힙 큐에서 빼는 총 수가 n임을 의미합니다. 각 노드에는 잠재적으로 각 에지에 대해 한 번 호출되는 감소 키가 있으므로 수행 된 감소 키의 총 수는 최대 m입니다. 이것은 (n T e + n T d + m T k ) 의 런타임을 제공하며 , 여기서 T k 는 감소 키를 호출하는 데 필요한 시간입니다.
그렇다면 이것이 런타임에 어떤 영향을 미칩니 까? 사용하는 우선 순위 대기열에 따라 다릅니다. 다음은 다양한 우선 순위 대기열과 다양한 Dijkstra 알고리즘 구현의 전체 런타임을 보여주는 빠른 표입니다.
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의 알고리즘은 감소 키를 사용할 때 점근 적으로 더 효율적입니다.
간단히 말해서, 감소 키와 좋은 우선 순위 대기열을 사용하면 대기열에 추가 및 대기열에서 빼기를 계속하면 가능한 것 이상으로 Dijkstra의 점근 적 런타임을 삭제할 수 있습니다.
이 점 외에도 Gabow의 최단 경로 알고리즘과 같은 일부 고급 알고리즘은 Dijkstra의 알고리즘을 서브 루틴으로 사용하고 감소 키 구현에 크게 의존합니다. 그들은 유효한 거리의 범위를 미리 알고 있다면 그 사실을 기반으로 매우 효율적인 우선 순위 대기열을 만들 수 있다는 사실을 사용합니다.
도움이 되었기를 바랍니다!