Dijkstra의 알고리즘을 사용한 음의 가중치


113

Dijkstra의 알고리즘이 음의 가중치로 작동하지 않는 이유를 이해하려고합니다. Shortest Paths 에 대한 예제를 읽고 다음 시나리오를 파악하려고합니다.

    2
A-------B
 \     /
3 \   / -2
   \ /
    C

웹 사이트에서 :

모서리가 모두 왼쪽에서 오른쪽으로 향한다고 가정하면 A로 시작하면 Dijkstra의 알고리즘은 d (A, A) + length (edge), 즉 (A, B)를 최소화하는 모서리 (A, x)를 선택합니다. 그런 다음 d (A, B) = 2를 설정하고 d (A, y) + d (y, C)를 최소화하는 다른 모서리 (y, C)를 선택합니다. 유일한 선택은 (A, C)이며 d (A, C) = 3으로 설정됩니다. 그러나 총 길이가 1 인 C를 통해 A에서 B까지의 최단 경로를 찾지 못합니다.

나는 익스트라의 다음 구현, D [B]를 사용하는 이유에 업데이트되지 않습니다 이해할 수없는 1, C 정점 알고리즘에 도달, 그것은 A가 B에서 휴식을 실행하면 (는 D [B]가 일치 한 것을 볼 수 2있으므로, 업데이트 및 값 1).

Dijkstra(G, w, s)  {
   Initialize-Single-Source(G, s)
   S ← Ø
   Q ← V[G]//priority queue by d[v]
   while Q ≠ Ø do
      u ← Extract-Min(Q)
      S ← S U {u}
      for each vertex v in Adj[u] do
         Relax(u, v)
}

Initialize-Single-Source(G, s) {
   for each vertex v  V(G)
      d[v] ← ∞
      π[v] ← NIL
   d[s] ← 0
}

Relax(u, v) {
   //update only if we found a strictly shortest path
   if d[v] > d[u] + w(u,v) 
      d[v] ← d[u] + w(u,v)
      π[v] ← u
      Update(Q, v)
}

감사,

Meir


일반적으로 음의 가장자리 가중치를 사용하는 길 찾기는 매우 어렵습니다. 어떤 경로를 찾든 상관없이 어딘가에 임의의 큰 음의 가장자리 가중치가있는 임의의 긴 경로가 항상있을 가능성이 있습니다. NP 완료라면 놀라지 않을 것입니다.
닉 존슨

4
이 의심이있는 다른 사람은 음의 가중치주기가없는 그래프 GIVEN에서 최단 경로를 찾을 수 있습니다. 위의 알고리즘은 relax가 실제로 성공했을 때 Relax 함수가 "true"값을 반환 한 경우 작동합니다.이 경우 인접 정점 "v"가 없으면 우선 순위 대기열에 포함되거나 이미있는 경우 업데이트됩니다. 이는 방문한 노드가 계속 완화됨에 따라 우선 순위 대기열에 다시 추가 될 수 있음을 의미합니다.
goelakash

답변:


202

제안한 알고리즘은 실제로이 그래프에서 가장 짧은 경로를 찾을 수 있지만 일반적으로 모든 그래프는 아닙니다. 예를 들어 다음 그래프를 고려하십시오.

그래프 그림

예에서와 같이 가장자리가 왼쪽에서 오른쪽으로 향한다고 가정합니다.

알고리즘은 다음과 같이 작동합니다.

  1. 첫째, 당신은 설정 d(A)zero와에 다른 거리 infinity.
  2. 그런 다음 노드를 확장 하여 , to 및 로 A설정 합니다 .d(B)1d(C)zerod(D)99
  3. 다음으로, C순 변경없이 확장합니다 .
  4. 그런 다음 확장하여 B아무 효과가 없습니다.
  5. 마지막으로, 당신은 확장 D변경하는 d(B)-201.

이 말에,하지만, 그주의하는 것이 d(C)여전히 0, 최단 경로가 비록 C길이 -200. 따라서 알고리즘이 경우에 따라 거리를 정확하게 계산하지 못합니다. 또한 각 노드에서 시작 노드로 이동하는 방법을 알려주는 백 포인터를 저장하더라도에서 A로 돌아가는 잘못된 경로를 사용하게 C됩니다 A.


35
훌륭한 답변에 추가하려면 : Dijkstra는 탐욕스러운 알고리즘이라는 것이 근시안적인 선택의 이유입니다.
blubb 2011

4
기술적으로이 그래프의 모든 경로는 음의 순환 A, D, B, A에 따라 음의 무한대 비용이 있음을 지적하고 싶습니다.
Nate

2
@ Nate- 명확히하기 위해 그래프의 모든 가장자리는 왼쪽에서 오른쪽으로 향합니다. 고품질 ASCII 아트에서 화살표를 렌더링하는 것은 다소 어려웠습니다. :-)
templatetypedef

2
이전에 음의 가장자리가있는 그래프를 본 적이없는 사람들을 위해이 그래프에 대한 유용한 해석이 가장자리 가중치가 지불하는 통행료를 제공하는 유료 도로 네트워크라는 것을 발견했습니다. -300 도로는 $ 300를주는 미친 후진 유료 도로입니다.
D Coetzee

3
@ SchwitJanwityanujit- 이것이 Dijkstra의 알고리즘이 작동하는 방식입니다. 알고리즘은 경로를 탐색하지 않고 대신 노드 를 처리하여 작동합니다 . 각 노드는 정확히 한 번만 처리되므로 B 노드를 처리하고 거리가 1이되는 즉시 노드 B를 다시 방문하거나 거리를 업데이트하지 않습니다.
templatetypedef

25

Dijkstra는 그래프에 음의 사이클이없는 경우, 즉 합산 가중치가 0보다 작은 사이클의 경우 음의 가중치에 대해서도 작동합니다.

물론 부정적인 사이클이 없더라도 templatetypedef Dijkstra가 만든 예제에서 실제로는 사이클조차도 실패하는 이유를 물을 수 있습니다. 이는 그가 대상 노드에 도달하자마자 알고리즘을 보유하는 또 다른 중지 기준을 사용하고 있기 때문입니다 (또는 모든 노드가 한 번 정산되었으며 정확히 지정하지 않았습니다). 음의 가중치가없는 그래프에서는 잘 작동합니다.

우선 순위 대기열 (힙)이 비어있을 때 알고리즘을 중지하는 대체 중지 기준을 사용하는 경우 (이 중지 기준은 질문에서도 사용됨), dijkstra는 가중치가 음수이지만없는 그래프에서도 올바른 거리를 찾습니다. 부정적인 사이클.

그러나이 경우 음의주기가없는 그래프에 대한 dijkstra의 점근 시간 경계가 손실됩니다. 이는 음의 가중치로 인해 더 나은 거리가 발견되면 이전에 정착 된 노드를 힙에 다시 삽입 할 수 있기 때문입니다. 이 속성을 레이블 수정이라고합니다.


2. 왜 시간이 내가 "벨만-포드에 더 가깝고"지수 적 (벨만-포드보다 더 나쁘다)이 아니라고 생각하는지는 분명하지 않다. 구체적인 알고리즘과 증거가 있습니까?
Gassa 2014-08-06

3
1. : 언급 된 중지 기준으로 정확히 동일한 dijkstra 구현을 사용할 수 있으므로 대기열이 비어있을 때 중지됩니다 (원래 질문의 의사 코드 참조), 다르게 동작하더라도 최단 경로에 대한 dijkstras 알고리즘입니다 노드를 여러 번 정착 (라벨 수정).
infty10000101 2014-08-06

1
To 2 .: 그건 추측 일 뿐이므로 삭제하겠습니다. 탐험해야 할 경로가 기하 급수적으로 많기 때문에 기하 급수적 인 시간에 맞다고 생각합니다.
infty10000101 2014-08-06

11

알고리즘의 어느 곳에서도 S를 사용하지 않았습니다 (수정하는 것 외에). dijkstra의 아이디어는 정점이 S에 있으면 다시 수정되지 않습니다. 이 경우 B가 S 안에 있으면 C를 통해 다시 연결할 수 없습니다.

이 사실은 O (E + VlogV)의 복잡성을 보장합니다. [그렇지 않으면 가장자리를 한 번 더 반복하고 정점을 한 번 더 반복합니다.]

즉, 게시 한 알고리즘이 dijkstra의 알고리즘에서 약속 한대로 O (E + VlogV)에 없을 수 있습니다.


또한, 완전히 경로 비용 만 반복 가장자리 증가시킬 수 있다는 가정을 파괴 부정적인 체중 가장자리없이 정점을 수정할 필요가 없습니다
prusswan

이 가정은 정확히 우리가 S를 사용할 수있게 해주는 것이며, 정점이 S에 있으면 '알면'다시는 수정되지 않습니다.
amit

마지막 진술이 잘못되었습니다. 게시 된 알고리즘은 음의 모서리가없는 그래프에서 작동 할 때 시간 복잡도 O (E + VlogV)를 갖습니다. 이미 방문한 노드를 확인할 필요가 없습니다. 방문한 사실은 이완 절차가 해당 노드를 대기열에 한 번 더 추가하지 않도록 보장하기 때문입니다.
Pixar

7

Dijkstra는 Greedy 접근 방식이므로 일단 정점이이 루프를 방문한 것으로 표시되면 나중에 도달하는 데 더 적은 비용이 드는 다른 경로가 있더라도 다시 평가되지 않습니다. 그리고 이러한 문제는 그래프에 음의 모서리가있을 때만 발생할 수 있습니다.


욕심이 알고리즘은 , 이름에서 알 수 있듯이, 항상 그 순간에 가장 좋은 것 같다 선택을합니다. 주어진 지점에서 최적화 (최대화 또는 최소화)해야하는 목적 함수가 있다고 가정합니다. Greedy 알고리즘은 목표 함수가 최적화되도록 각 단계에서 탐욕스러운 선택을합니다 . Greedy 알고리즘은 최적의 솔루션을 계산할 기회가 하나뿐 이므로 절대로 돌아가서 결정을 되 돌리지 않습니다.


4

요약 : 대답은 구현에 따라 다릅니다. 게시 한 의사 코드의 경우 음의 가중치로 작동합니다.


Dijkstra 알고리즘의 변형

핵심은 Dijkstra의 알고리즘 구현에는 3 가지 종류가 있지만이 질문에 대한 모든 답변은 이러한 변형 간의 차이점을 무시합니다.

  1. 중첩 for루프 를 사용하여 정점을 완화합니다. 이것은 Dijkstra의 알고리즘을 구현하는 가장 쉬운 방법입니다. 시간 복잡도는 O (V ^ 2)입니다.
  2. Priority-queue / heap 기반 구현 + 재진입은 허용되지 않습니다. 여기서 재진입은 완화 된 정점이 나중에 다시 완화되도록 우선 순위 대기열로 다시 푸시 될 수 있음을 의미합니다 .
  3. 우선 순위 대기열 / 힙 기반 구현 + 재진입 허용.

버전 1과 2는 가중치가 음수 인 그래프에서 실패하지만 (이런 경우 정답을 얻으면 우연의 일치 일뿐입니다) 버전 3은 여전히 ​​작동합니다. .

원래 문제로 게시 된 의사 코드는 위의 버전 3이므로 음의 가중치로 작동합니다.

다음은 Algorithm (4th edition) 의 좋은 참조입니다. 여기 에는 위에서 언급 한 버전 2 및 3의 Java 구현이 포함되어 있습니다.

Q. Dijkstra의 알고리즘은 음의 가중치로 작동합니까?

A. 예, 아니오. 정점을 우선 순위 대기열에 두 번 이상 대기열에 넣을 수 있는지 여부에 따라 Dijkstra의 알고리즘으로 알려진 두 개의 최단 경로 알고리즘이 있습니다. 가중치가 음수가 아닌 경우 두 버전이 일치합니다 (정점이 두 번 이상 대기열에 추가되지 않으므로). DijkstraSP.java에서 구현 된 버전 (정점을 두 번 이상 대기열에 넣을 수 있음)은 음의 에지 가중치 (음의주기는 없음)가있을 때 정확하지만 최악의 경우 실행 시간은 기하 급수적입니다. (우리는 에지 가중 digraph에 음의 가중치를 가진 에지가있는 경우 DijkstraSP.java에서 예외가 발생하므로 프로그래머가이 지수 동작에 놀라지 않습니다.) 정점을 대기열에 넣을 수 없도록 DijkstraSP.java를 수정하는 경우 두 번 이상 (예 : 표시된 [] 배열을 사용하여 완화 된 정점을 표시)


자세한 구현 세부 사항 및 Bellman-Ford 알고리즘과 버전 3의 연결에 대해서는 zhihu의 답변을 참조하십시오 . 내 대답이기도하다 (중국어로). 현재는 영어로 번역 할 시간이 없습니다. 누군가이 이것을 할 수 있고 stackoverflow 에서이 답변을 편집 할 수 있다면 정말 감사합니다.


1

B와 C 사이를 오가면 어떻게되는지 생각해보세요 ...

(그래프가 지시되지 않은 경우에만 관련됨)

편집 됨 : 문제는 AC *가있는 경로가 음의 가중치 모서리가있는 경우 AB보다 더 나을 수 있다는 사실과 관련이 있다고 생각합니다. 따라서 비 가정이라는 가정하에 AC를 따라가는 위치는 중요하지 않습니다. 네거티브 웨이트 에지 AC가 된 후 B에 도달하기로 선택하면 AB보다 더 나은 경로를 찾는 것은 불가능합니다.


이것은 가능하지 않으며 그래프가 지시됩니다.
아 미트

@amit : 좋은 지적, 나는 그것을 놓쳤다. 시간 문제를 재고하기
prusswan

1

"2) 마이너스 가중치가있는 그래프의 최단 경로에 Dijksra 알고리즘을 사용할 수 있습니까? 한 가지 아이디어는 최소 가중치 값을 계산하고 모든 가중치에 양수 값 (최소 가중치 값의 절대 값과 동일)을 추가하고 Dijksra 알고리즘을 실행하는 것입니다. 수정 된 그래프의 경우이 알고리즘이 작동합니까? "

모든 최단 경로의 길이가 같지 않으면 절대적으로 작동하지 않습니다. 예를 들어 길이가 두 모서리 인 최단 경로가 주어지고 각 모서리에 절대 값을 추가 한 후 총 경로 비용은 2 * | 최대 음수 가중치 |만큼 증가합니다. 반면에 길이가 3 개인 또 다른 경로이므로 경로 비용은 3 * | 최대 음의 가중치 |로 증가합니다. 따라서 모든 고유 경로가 다른 양만큼 증가합니다.


0

네거티브 사이클을 포함하지 않는 네거티브 에지로 dijkstra의 알고리즘을 사용할 수 있지만 정점을 여러 번 방문 할 수 있으며 해당 버전은 빠른 시간 복잡성을 잃게됩니다.

이 경우 실질적으로 정상적인 대기열이 있고 네거티브 에지를 처리 ​​할 수있는 SPFA 알고리즘 을 사용하는 것이 더 낫다는 것을 알았습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.