πŸ’‘ μ΅œλ‹¨ 경둜 μ•Œκ³ λ¦¬μ¦˜

πŸ’­ ν•˜λ‚˜μ˜ μΆœλ°œμ μ—μ„œ λ‚˜λ¨Έμ§€ λͺ¨λ“  λͺ©μ μ§€μ— λŒ€ν•œ μ΅œλ‹¨ 경둜λ₯Ό κ΅¬ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜

  • λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜
  • 벨만 ν¬λ“œ μ•Œκ³ λ¦¬μ¦˜

πŸ’­ λͺ¨λ“ (μΆœλ°œμ§€, λͺ©μ μ§€) μŒμ— λŒ€ν•œ μ΅œλ‹¨ 경둜λ₯Ό κ΅¬ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜

  • ν”Œλ‘œμ΄λ“œ μ›Œμ…œ μ•Œκ³ λ¦¬μ¦˜
    • λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ°μ˜ λŒ€ν‘œμ μΈ 예

πŸ“Œ λ‹€μ΅μŠ€νŠΈλΌ

  • λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž¨μ„ ν™œμš©ν•œ λŒ€ν‘œμ μΈ μ΅œλ‹¨ 경둜 탐색 μ•Œκ³ λ¦¬μ¦˜
  • νŠΉμ •ν•œ ν•˜λ‚˜μ˜ μ •μ μ—μ„œ λ‹€λ₯Έ λͺ¨λ“  μ •μ μœΌλ‘œ κ°€λŠ” μ΅œλ‹¨ 경둜λ₯Ό μ•Œλ €μ€Œ
  • μΈκ³΅μœ„μ„± gps μ†Œν”„νŠΈμ›¨μ–΄ λ“±μ—μ„œ κ°€μž₯ 많이 μ‚¬μš©
  • ν”„λ¦Ό μ•Œκ³ λ¦¬μ¦˜κ³Ό 맀우 μœ μ‚¬
    • νƒμš• μ•Œκ³ λ¦¬μ¦˜μ— 기반
  • 음수 κ°€μ€‘μΉ˜λ₯Ό μΈμ •ν•˜μ§€ μ•ŠμŒ
    • 음수 간선이 μžˆμœΌλ©΄Β λ°μ΄ν¬μŠ€νŠΈλΌΒ λŒ€μ‹ μ—Β λ²¨λ§Œ-ν¬λ“œΒ μ•Œκ³ λ¦¬μ¦˜μ΄λ‚˜Β SPFAλ₯Ό μ‚¬μš©
    • μžμ„Έν•œ μ„€λͺ…은 λ’·λΆ€λΆ„μ—μ„œ μ„€λͺ…ν•  μ˜ˆμ •
  • ν˜„μ‹€ μ„Έκ³„μ—μ„œλŠ” 음의 간선이 μ‘΄μž¬ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— λ‹€μ΅μŠ€νŠΈλΌλŠ” ν˜„μ‹€ 세계에 μ‚¬μš©ν•˜κΈ° 맀우 μ ν•©ν•œ μ•Œκ³ λ¦¬μ¦˜ 쀑 ν•˜λ‚˜

πŸ”Ž λ‹€μ΄λ‚˜λ―Ή ν”„κ·Έλž˜λ°μœΌλ‘œ λ§ν•˜λŠ” 이유 πŸ”
- μ΅œλ‹¨κ±°λ¦¬λŠ” μ—¬λŸ¬ 개의 μ΅œλ‹¨ 거리둜 이루어져 있음
- a μ—μ„œ b 둜 κ°€κ³  b μ—μ„œ c 둜 κ°€κ³  c μ—μ„œ d 둜 κ°€λŠ” κ²½λ‘œκ°€ a μ—μ„œ d 둜 κ°€λŠ” μ΅œλ‹¨ 경둜라면
κ·Έ κ³Όμ • 속에 있던 a μ—μ„œ b 둜 κ°€λŠ” 각 κ²½λ‘œλ“€λ„ μ΅œμ†Œκ°€ λ˜μ–΄μ•Ό 함
- ν•˜λ‚˜μ˜ μ΅œλ‹¨ 거리λ₯Ό ꡬ할 λ•Œ κ·Έ μ΄μ „κΉŒμ§€ κ΅¬ν–ˆλ˜ μ΅œλ‹¨ 거리 정보λ₯Ό κ·ΈλŒ€λ‘œ μ‚¬μš©ν•˜λŠ” νŠΉμ§•μ΄ 있음

> μœ„μ™€ 같은 νŠΉμ§• λ•Œλ¬Έμ— μž‘μ€ λ¬Έμ œκ°€ 큰 문제 속에 λΉ„μŠ·ν•œ ν˜•νƒœλ‘œ ν¬ν•¨λ˜μ–΄ μžˆλŠ” λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ°
ν˜•νƒœλ‘œ λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ”Ž 그리디 μ•Œκ³ λ¦¬μ¦˜μœΌλ‘œ λ§ν•˜λŠ” 이유 πŸ”
> 정렬을 μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— μ •λ ¬ 이후에 κ°€μž₯ 적은 것을 μ„ νƒν•˜λŠ” 것이 μ•Œκ³ λ¦¬μ¦˜μ— ν¬ν•¨λ˜κΈ°μ— 그리디 μ•Œκ³ λ¦¬μ¦˜
μœΌλ‘œλ„ λΆ„λ₯˜λ  수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ“Œ λ‹€μ΅μŠ€νŠΈλΌ - Relax μ—°μ‚°

본격적인 λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜ μ„€λͺ…에 μ•žμ„œ κ°€μž₯ 핡심적인 Relax 연산에 λŒ€ν•΄ λ¨Όμ € μ„€λͺ…ν•˜κ² μŠ΅λ‹ˆλ‹€.

png

1λΆ€ν„° λ‹€λ₯Έ λͺ¨λ“  λ…Έλ“œλ‘œ κ°€λŠ” μ΅œλ‹¨ 경둜λ₯Ό κ΅¬ν•œλ‹€κ³  κ°€μ •ν•΄λ΄…μ‹œλ‹€.

ν˜„μž¬ μ ‘κ·Όν•  수 μžˆλŠ” λ…Έλ“œλŠ” 1 밖에 μ—†λ‹€κ³  κ°€μ •ν•œλ‹€λ©΄, 1 에 μΈμ ‘λ…Έλ“œμΈ 2, 3, 4 κΉŒμ§€μ˜ μ΅œλ‹¨ κ±°λ¦¬λŠ”
각각 3, 6, 7 둜 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

png

λ‹€μŒμœΌλ‘œ λ…Έλ“œ 2 λ₯Ό μ²˜λ¦¬ν•  수 있게 λ˜μ—ˆλ‹€λ©΄,

1 - 3 (6) 의 λΉ„μš©λ³΄λ‹€ 1 - 2 - 3 (3 + 1) 을 ν†΅ν•œ κ²½λ‘œκ°€ λΉ„μš©μ΄ 더 μ €λ ΄ν•œ 것을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€.

이 λ•Œ, μ•Œκ³ λ¦¬μ¦˜μ—μ„œλŠ” 기쑴에 μ•Œκ³  있던 3 으둜 κ°€λŠ” μ΅œμ†Œ λΉ„μš©μ„ 6μ—μ„œ 4 둜 μƒˆλ‘œ κ°±μ‹ ν•˜κ²Œ λ©λ‹ˆλ‹€.

μ΄λ ‡κ²Œ λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜μ€ ν˜„μž¬κΉŒμ§€ μ•Œκ³  있던 μ΅œλ‹¨ 경둜λ₯Ό κ°±μ‹ ν•˜λ©° λ…Έλ“œ 별 μ΅œλ‹¨ 경둜λ₯Ό 찾게 λ˜λŠ”λ°
μ΄λŸ¬ν•œ 연산을 relax 라 ν•˜λ©°, 이런 연산을 ν•˜λŠ” 것을 relaxation 이라 ν•©λ‹ˆλ‹€.

πŸ“Œ λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜ λ™μž‘ κ³Όμ •

png

μœ„μ˜ κ·Έλž˜ν”„λ₯Ό 톡해 λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜μ˜ λ™μž‘ 과정에 λŒ€ν•΄ μžμ„Ένžˆ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.


κ°€μ€‘μΉ˜λŠ” κ°€μ€‘μΉ˜ 인접 ν–‰λ ¬ 이라 λΆˆλ¦¬λŠ” 2차원 배열에 μ €μž₯ν•©λ‹ˆλ‹€. μ΄λ•Œ 자기 μžμ‹ μ˜ λŒ€ν•œ κ°€μ€‘μΉ˜λŠ” 0으둜 ν‘œμ‹œν•©λ‹ˆλ‹€. 자기 μžμ‹ μ— λŒ€ν•œ κ°€μ€‘μΉ˜ 값이 0 으둜 λ‚˜νƒ€λ‚΄κΈ° λ•Œλ¬Έμ— λ…Έλ“œκ°„ 간선이 μ—†μŒμ„ λ‚˜νƒ€λ‚Ό λ•Œ λŠ” 0 μ΄λΌλŠ” κ°’ λŒ€μ‹  λ¬΄ν•œλŒ€ 의 값을 μ‚¬μš©ν•©λ‹ˆλ‹€.

png


λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜μ—μ„œλŠ” μ‹œμž‘ μ •μ μ—μ„œ 집합 S 에 μžˆλŠ” μ •μ λ§Œμ„ κ±°μ³μ„œ λ‹€λ₯Έ μ •μ μœΌλ‘œ κ°€λŠ”
μ΅œλ‹¨ 거리λ₯Ό κΈ°λ‘ν•˜λŠ” 배열이 λ°˜λ“œμ‹œ μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.

  • 집합 S λŠ” μ΅œλ‹¨ 거리에 ν•΄λ‹Ήν•˜λŠ” 정점이 ν•˜λ‚˜μ”© μΆ”κ°€λ©λ‹ˆλ‹€.
  • 집합 S 에 μ†ν•œ 정점듀은 relax μ—°μ‚°μœΌλ‘œ 인해 μ΅œλ‹¨ 거리가 ꡬ해진 정점듀이기에 μΆ”κ°€λœ 이후뢀턴
    μƒˆλ‘œ κ°±μ‹ λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • 처음 μ‹œμž‘ μ‹œ S = {v} 이며
    • vλŠ” μ‹œμž‘ 정점을 μ˜λ―Έν•©λ‹ˆλ‹€.
    • μ΅œλ‹¨ 거리가 λ°œκ²¬λ˜λŠ” 정점듀이 이후에 집합 S에 ν•˜λ‚˜μ”© μΆ”κ°€λ©λ‹ˆλ‹€.
    • 집합 S 에 λͺ¨λ“  정점이 μ†ν•˜κ²Œ 될 경우 μ•Œκ³ λ¦¬μ¦˜μ€ μ’…λ£Œλ©λ‹ˆλ‹€.

μ΅œλ‹¨ 거리λ₯Ό κΈ°λ‘ν•˜λŠ” 1차원 λ°°μ—΄μ˜ 이름을 distance 라 ν•˜κ² μŠ΅λ‹ˆλ‹€.
이 λ•Œ μ‹œμž‘ 정점을 v 라고 ν•œλ‹€λ©΄, distance[v]=0 이며 λ‹€λ₯Έ 정점에 λŒ€ν•œ distance 값은 μ‹œμž‘ 정점과 ν•΄λ‹Ή 정점 κ°„μ˜ κ°€μ€‘μΉ˜κ°€ λ©λ‹ˆλ‹€. μœ„μ— λ³΄μ—¬λ“œλ Έλ˜ κ°€μ€‘μΉ˜ 인접 행렬을 weight 라 ν–ˆμ„ λ•Œ $distance[w] = weight[v][w]$ 둜 말할 수 μžˆμŠ΅λ‹ˆλ‹€.

μ•Œκ³ λ¦¬μ¦˜μ˜ 맀 λ‹¨κ³„μ—μ„œ 집합 S μ•ˆμ— μžˆμ§€ μ•Šμ€ 정점 μ€‘μ—μ„œ κ°€μž₯ distance 값이 μž‘μ€ 정점을 S에 μΆ”κ°€ν•˜κ²Œ λ©λ‹ˆλ‹€.
μƒˆλ‘œμš΄ 정점 uκ°€ S에 μΆ”κ°€λ˜λ©΄, S에 μžˆμ§€ μ•Šμ€ λ‹€λ₯Έ μ •μ λ“€μ˜ distance 값을 μˆ˜μ •ν•©λ‹ˆλ‹€.

distance값은 relax 연산을 톡해 κ·Έ μ΅œμ†Œκ°’μ„ 찾게 λ˜λŠ”λ° μ΄λŠ” λ‹€μŒκ³Ό 같은 μ‹μœΌλ‘œ ν‘œν˜„λ  수 μžˆμŠ΅λ‹ˆλ‹€.

\[distance[w] = min(distance[w], distance[u] + weight[u][w])\]



이제 μ‹€μ œ λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜μ˜ λ™μž‘ 과정에 λŒ€ν•΄ λ”°λΌκ°€λ³΄κ² μŠ΅λ‹ˆλ‹€.

μ‹œμž‘μ •μ μ„ 0으둜 μž‘μ•˜λ‹€κ³  κ°€μ •ν•΄λ΄…μ‹œλ‹€.

png

집합 S μ—λŠ” μ‹œμž‘μ •μ μΈ 0 이 λ“€μ–΄κ°€ μžˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ distance λ°°μ—΄μ—λŠ” μžκΈ°μžμ‹ μ˜ λΉ„μš©μ€ 0 이며
μ—°κ²°λ˜μ–΄ μžˆμ§€ μ•ŠλŠ” 정점듀은 λ¬΄ν•œλŒ€λ‘œ ν‘œμ‹œλ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

이제 정점 0 의 μž…μž₯μ—μ„œ κ°€μž₯ 짧은 거리의 정점을 μ°Ύμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

μš°μ„  간선이 μ§μ ‘μ μœΌλ‘œ μ—°κ²°λ˜μ–΄μžˆμ§€ μ•Šμ•„μ„œ λΉ„μš©μ΄ λ¬΄ν•œλŒ€λ‘œ ν‘œμ‹œλ˜μ–΄ μžˆλŠ” 2, 3, 6이 제일 λ¨Όμ € μ œμ™Έλ©λ‹ˆλ‹€.

이 ν›„, 인접정점인 4, 1, 5 정점 쀑 3으둜 κ°€μž₯ 적은 λΉ„μš©μ„ 가지고 μžˆλŠ” 정점 4κ°€ 집합 S에 μΆ”κ°€λ©λ‹ˆλ‹€.


png

μƒˆλ‘œμš΄ 정점이 집합 S에 μΆ”κ°€ λ˜μ—ˆμœΌλ―€λ‘œ λ‹€λ₯Έ μ •μ λ“€μ˜ distance 값이 λ³€κ²½λ©λ‹ˆλ‹€.

정점 0 μ—μ„œ 간선이 μ΄μ–΄μ Έμžˆμ§€ μ•Šμ•„ λ¬΄ν•œλŒ€λ‘œ ν‘œμ‹œλ˜μ–΄μžˆλ˜ 정점 3κ³Ό 6이 정점 4λ₯Ό ν†΅ν•΄μ„œ 접근이 κ°€λŠ₯ν•΄μ‘ŒμœΌλ―€λ‘œ
값이 μƒˆλ‘œ λ³€κ²½ λ©λ‹ˆλ‹€.

λ˜ν•œ relax 연산을 톡해 정점 1의 distance 값이 μ΅œμ†Œκ°’μœΌλ‘œ 값이 λ³€κ²½ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

λ‹€μŒμœΌλ‘œ 집합 S에 μ†ν•˜μ§€ μ•Šμ€ 정점 쀑 κ°€μž₯ 적은 λΉ„μš©μ„ 가지고 μžˆλŠ” 정점 1 을 μ„ νƒν•©λ‹ˆλ‹€.

정점 1을 집합 S에 μƒˆλ‘œ μΆ”κ°€ν•˜κ³  λ§ˆμ°¬κ°€μ§€λ‘œ λ‹€λ₯Έ μ •μ λ“€μ˜ distance 값을 μƒˆλ‘œ λ³€κ²½ν•©λ‹ˆλ‹€.



png

정점 2 에 λŒ€ν•΄ 정점 1을 톡해 접근이 κ°€λŠ₯ν•˜κ²Œ λ˜μ—ˆμœΌλ―€λ‘œ relax 연산을 톡해 κΈ°μ‘΄ λ¬΄ν•œλŒ€μ˜ κ°’μ—μ„œ 9λΌλŠ” μ΅œμ†Œκ°’μ„ μƒˆλ‘œ λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

λ‹€μŒμœΌλ‘œ 집합 S에 μ†ν•˜μ§€ μ•Šμ€ 정점 쀑 κ°€μž₯ 적은 λΉ„μš©μ„ 가지고 μžˆλŠ” 정점 6을 μ„ νƒν•˜μ—¬ μƒˆλ‘œ S에 μΆ”κ°€ν•©λ‹ˆλ‹€.

png

집합 S에 정점 6이 μΆ”κ°€λ¨μœΌλ‘œμ¨ 정점 3 에 λŒ€ν•œ 정보가 14 β†’ 12 둜 μƒˆλ‘œ λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

(distance[3] = min(distance[3], distance[6] + weight(6, 3) = min(14, 8 + 4) = 12 )


λ‹€μŒμœΌλ‘œ 집합 S에 μ†ν•˜μ§€ μ•Šμ€ 정점 쀑 κ°€μž‘ 적은 λΉ„μš©μ„ 가지고 μžˆλŠ” 정점 2 λ₯Ό μ„ νƒν•˜μ—¬ 집합 S에 μΆ”κ°€ν•΄μ€λ‹ˆλ‹€.



png

집합 S에 정점 2λ₯Ό μΆ”κ°€ν•¨μœΌλ‘œμ¨ 정점 3에 λŒ€ν•œ 정보가 relax 연산을 톡해 μƒˆλ‘œ λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

(distance[3] = min(distance[3], distance[2] + weight(2,3) = min(12, 9 + 2) = 11)


λ‹€μŒμœΌλ‘œ κ°€μž₯ 적은 λΉ„μš©μ„ 가지고 μžˆλŠ” 정점 5λ₯Ό 집합 S에 μΆ”κ°€ν•˜κ³  μœ„μ™€ 같은 과정을 거치며
정점 3κΉŒμ§€ 집합 S에 μΆ”κ°€ν•˜λ©΄ λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜μ€ μ’…λ£Œλ©λ‹ˆλ‹€.



Code

μœ„ μ˜ˆμ‹œλŠ” 이해λ₯Ό 돕기 μœ„ν•΄ κ°€μž₯ κ°„λ‹¨ν•œ ν‘œν˜„ λ°©μ‹μœΌλ‘œ μ„€λͺ…ν•œ μ˜ˆμ‹œμž…λ‹ˆλ‹€. μœ„μ˜ λ°©μ‹λŒ€λ‘œ μ½”λ“œλ₯Ό κ΅¬ν˜„ν•  경우 μ‹œκ°„λ³΅μž‘λ„κ°€ $O(n^2)$ 을 가지기 λ•Œλ¬Έμ— νš¨μœ¨μ μ΄μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 이λ₯Ό μ΅œμ†Œμš°μ„ μˆœμœ„νλ₯Ό μ‚¬μš©ν•˜λ©΄ μ΅œμ†Œμš°μ„ μˆœμœ„νμ—μ„œ popμ‹œ 거리가 κ°€μž₯ 적은 값이 λ‚˜μ˜€κΈ° λ•Œλ¬Έμ— μ‹œκ°„λ³΅μž‘λ„λ₯Ό $O(nlogn)$ 으둜 λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€. μ•„λž˜μ˜ κ΅¬ν˜„ μ½”λ“œλŠ” 이λ₯Ό λ°˜μ˜ν•œ μ½”λ“œμž…λ‹ˆλ‹€.

from heapq import heappush, heappop

class MinPriorityQueue:
    def __init__(self):
        self.heap = []
    def push(self, item):
        heappush(self.heap, item)
    
    def pop(self):
        return heappop(self.heap)

class ShortestPath:
    def __init__(self, s, distance, p):
        self.source = s
        self.distance = distance
        self.p = p
    def print_shortest_path(self, dest):
        if self.source == dest:
            print(dest, end= " ")
            return
        if self.p[dest] != None:
            self.print_shortest_path(self.p[dest])
        else:
            print("There is no path")
            return
        print(dest, end=" ")

class Graph:
    BIG_NUMBER = 2000
    def __init__(self, vertex_num):
        self.adj_matrix = [[None for _ in range(vertex_num)] for _ in range(vertex_num)]
        self.vertex_num = vertex_num
    def add_edge(self, u, v, w):
        self.adj_matrix[u][v] = w


    def dijkstra(self, s):
        distance = [self.BIG_NUMBER for _ in range(self.vertex_num)]
        p = [None for _ in range(self.vertex_num)]

        S = set()
        pq = MinPriorityQueue()
        for i in range(self.vertex_num):
            pq.push((self.BIG_NUMBER, i))
        distance[s] = 0
        pq.push((0, s))

        while len(S) < self.vertex_num:
            d, v = pq.pop()
            print(d,v)
            
            if distance[v] != d:
                continue
        
            S.add(v)
            print(f'S: {S}')
            adj_v = self.adjacent_set(v)
            for u, w_u_v in adj_v:
                if u not in S and distance[u] > distance[v] + w_u_v:
                    distance[u] = distance[v] + w_u_v
                    p[u] = v
                    pq.push((distance[u], u))

        sp = ShortestPath(s, distance, p)
        return sp

    def adjacent_set(self, v):
        adj_v = []
        for i in range(self.vertex_num):
            w = self.adj_matrix[v][i]
            if w:
                adj_v.append((i, w))
        return adj_v


if __name__ =="__main__":
    g = Graph(4)
    g.add_edge(0, 1, 10)
    g.add_edge(0, 2, 3)
    g.add_edge(1, 3, 5)
    g.add_edge(2, 1, 5)
    g.add_edge(2, 3, 8)
    g.add_edge(3, 1, 4)
    g.add_edge(3, 2, 12)
    source = 0
    sp = g.dijkstra(source)
    for i in range(g.vertex_num):
        print(f"distance[{i}] : {sp.distance[i]}, p[{i}] : {sp.p[i]}")
    dest = 3 
    print(f"path from {source} to {dest}")
    sp.print_shortest_path(dest)
    print() 



πŸ’­ 음수 간선이 μ‘΄μž¬ν•˜κ²Œ 될 경우 λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 이유

  • (κ°€μ€‘μΉ˜μ˜ 합이 음수인) 음수 μ‚¬μ΄ν΄μ˜ λ°œμƒ κ°€λŠ₯μ„±

png

  • μ‹œμž‘μ μ„ A 라 ν•  λ•Œ, A β†’ D κΉŒμ§€ μ΅œλ‹¨ κ²½λ‘œλŠ”?
  • A-B-C-D: 60
  • A-B-C-A-B-C-D: 10
  • A-B-C-A-B-C-A-B-C-D: -40

β†’ κ°€μ€‘μΉ˜μ˜ 합이 음수인 사이클이 μ‘΄μž¬ν•˜κ²Œ 되면 μ΅œλ‹¨ κ²½λ‘œκ°€ 음의 λ¬΄ν•œλŒ€λ‘œ λ°œμ‚°ν•˜λŠ” λ¬Έμ œκ°€ μƒκΉλ‹ˆλ‹€.



  • Edge Relaxation κ³„μ‚°μ˜ 였λ₯˜ κ°€λŠ₯μ„±

png

  • min-heap μš°μ„ μˆœμœ„ 큐λ₯Ό μ‚¬μš©ν•˜λ―€λ‘œ 초기 dist 값은 Aλ₯Ό μ œμ™Έν•˜κ³  λͺ¨λ‘ μ–‘μ˜ λ¬΄ν•œλŒ€
    • dist[A] + cost(A, C) < dist[C] 이기에 dist[C] λ₯Ό dist[A] + cost(A, C) 인 2 둜 relax 연산을 ν•΄μ£Όκ³  dist[B] 도 λ§ˆμ°¬κ°€μ§€λ‘œ relaxλ₯Ό ν•΄μ€Œ
    • 이 ν›„, A-C 의 κ°€μ€‘μΉ˜κ°€ A-B 의 κ°€μ€‘μΉ˜λ³΄λ‹€ μž‘κΈ° λ•Œλ¬Έμ—, pop μ‹œ C κ°€ λ¨Όμ € λ‚˜μ˜€κ²Œ 됨
    • 그리고 λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜μ€ Cλ₯Ό S 집합에 λ„£μ–΄μ£ΌκΈ° λ•Œλ¬Έμ— dist[C] λ₯Ό μ΅œλ‹¨κ±°λ¦¬λΌ μΈμ‹ν•˜κ³ 
      더이상 relaxλ₯Ό μ§„ν–‰ν•˜μ§€ μ•Šκ²Œλ¨

β†’ λ”°λΌμ„œ dist[C] λŠ” 2κ°€ λ˜μ§€λ§Œ μ΅œλ‹¨κ±°λ¦¬λŠ” -5 이여야 ν•˜λ―€λ‘œ μ•Œκ³ λ¦¬μ¦˜μ˜ 였λ₯˜κ°€ μƒκΈ°κ²Œ λ©λ‹ˆλ‹€. μ΄λŠ” λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜μ΄ 기본적으둜 minimum 에 minimum 을 λ”ν•˜λŠ” μ‹μœΌλ‘œ μž‘λ™ν•˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

μ‹œμž‘μ μ΄ minimum μ΄λΌλŠ” 원칙 μ•„λž˜μ— μΈμ ‘λ…Έλ“œλ“€μ„ μš°μ„ μˆœμœ„νμ— λ„£κ³ , κ°€μ€‘μΉ˜κ°€ μž‘μ€ 것듀뢀터 λ½‘μ•„μ„œ relax λ₯Ό ν•˜κΈ° λ•Œλ¬Έμ— minimum + minimum = minimum 을 μ΄μš©ν•˜μ—¬ μ΅œλ‹¨κ±°λ¦¬λ₯Ό μ°ΎκΈ°λ•Œλ¬Έ

Sources

  • https://m.blog.naver.com/ndb796/221234424646
  • https://mattlee.tistory.com/50
  • https://hy38.github.io/why-dijkstra-fail-on-a-negative-weighted-edge