π‘ μ΅λ¨ κ²½λ‘ μκ³ λ¦¬μ¦
π νλμ μΆλ°μ μμ λλ¨Έμ§ λͺ¨λ λͺ©μ μ§μ λν μ΅λ¨ κ²½λ‘λ₯Ό ꡬνλ μκ³ λ¦¬μ¦
- λ€μ΅μ€νΈλΌ μκ³ λ¦¬μ¦
- λ²¨λ§ ν¬λ μκ³ λ¦¬μ¦
π λͺ¨λ (μΆλ°μ§, λͺ©μ μ§) μμ λν μ΅λ¨ κ²½λ‘λ₯Ό ꡬνλ μκ³ λ¦¬μ¦
- νλ‘μ΄λ μμ
μκ³ λ¦¬μ¦
- λ€μ΄λλ―Ή νλ‘κ·Έλλ°μ λνμ μΈ μ
π λ€μ΅μ€νΈλΌ
- λ€μ΄λλ―Ή νλ‘κ·Έλ¨μ νμ©ν λνμ μΈ μ΅λ¨ κ²½λ‘ νμ μκ³ λ¦¬μ¦
- νΉμ ν νλμ μ μ μμ λ€λ₯Έ λͺ¨λ μ μ μΌλ‘ κ°λ μ΅λ¨ κ²½λ‘λ₯Ό μλ €μ€
- μΈκ³΅μμ± gps μννΈμ¨μ΄ λ±μμ κ°μ₯ λ§μ΄ μ¬μ©
- νλ¦Ό μκ³ λ¦¬μ¦κ³Ό λ§€μ° μ μ¬
- νμ μκ³ λ¦¬μ¦μ κΈ°λ°
- μμ κ°μ€μΉλ₯Ό μΈμ νμ§ μμ
- μμ κ°μ μ΄ μμΌλ©΄Β λ°μ΄ν¬μ€νΈλΌΒ λμ μ 벨λ§-ν¬λΒ μκ³ λ¦¬μ¦μ΄λΒ SPFAλ₯Ό μ¬μ©
- μμΈν μ€λͺ μ λ·λΆλΆμμ μ€λͺ ν μμ
- νμ€ μΈκ³μμλ μμ κ°μ μ΄ μ‘΄μ¬νμ§ μκΈ° λλ¬Έμ λ€μ΅μ€νΈλΌλ νμ€ μΈκ³μ μ¬μ©νκΈ° λ§€μ° μ ν©ν μκ³ λ¦¬μ¦ μ€ νλ
π λ€μ΄λλ―Ή νκ·Έλλ°μΌλ‘ λ§νλ μ΄μ π
- μ΅λ¨κ±°λ¦¬λ μ¬λ¬ κ°μ μ΅λ¨ κ±°λ¦¬λ‘ μ΄λ£¨μ΄μ Έ μμ
- a μμ b λ‘ κ°κ³ b μμ c λ‘ κ°κ³ c μμ d λ‘ κ°λ κ²½λ‘κ° a μμ d λ‘ κ°λ μ΅λ¨ κ²½λ‘λΌλ©΄
κ·Έ κ³Όμ μμ μλ a μμ b λ‘ κ°λ κ° κ²½λ‘λ€λ μ΅μκ° λμ΄μΌ ν¨
- νλμ μ΅λ¨ 거리λ₯Ό ꡬν λ κ·Έ μ΄μ κΉμ§ ꡬνλ μ΅λ¨ 거리 μ 보λ₯Ό κ·Έλλ‘ μ¬μ©νλ νΉμ§μ΄ μμ
> μμ κ°μ νΉμ§ λλ¬Έμ μμ λ¬Έμ κ° ν° λ¬Έμ μμ λΉμ·ν ννλ‘ ν¬ν¨λμ΄ μλ λ€μ΄λλ―Ή νλ‘κ·Έλλ°
ννλ‘ λ³Ό μ μμ΅λλ€.
π 그리λ μκ³ λ¦¬μ¦μΌλ‘ λ§νλ μ΄μ π
> μ λ ¬μ μ¬μ©νκΈ° λλ¬Έμ μ λ ¬ μ΄νμ κ°μ₯ μ μ κ²μ μ ννλ κ²μ΄ μκ³ λ¦¬μ¦μ ν¬ν¨λκΈ°μ 그리λ μκ³ λ¦¬μ¦
μΌλ‘λ λΆλ₯λ μ μμ΅λλ€.
π λ€μ΅μ€νΈλΌ - Relax μ°μ°
본격μ μΈ λ€μ΅μ€νΈλΌ μκ³ λ¦¬μ¦ μ€λͺ μ μμ κ°μ₯ ν΅μ¬μ μΈ Relax μ°μ°μ λν΄ λ¨Όμ μ€λͺ νκ² μ΅λλ€.
1λΆν° λ€λ₯Έ λͺ¨λ λ
Έλλ‘ κ°λ μ΅λ¨ κ²½λ‘λ₯Ό ꡬνλ€κ³ κ°μ ν΄λ΄
μλ€.
νμ¬ μ κ·Όν μ μλ λ
Έλλ 1
λ°μ μλ€κ³ κ°μ νλ€λ©΄, 1
μ μΈμ λ
ΈλμΈ 2, 3, 4 κΉμ§μ μ΅λ¨ 거리λ
κ°κ° 3, 6, 7 λ‘ λ³Ό μ μμ΅λλ€.
λ€μμΌλ‘ λ
Έλ 2
λ₯Ό μ²λ¦¬ν μ μκ² λμλ€λ©΄,
1 - 3 (6) μ λΉμ©λ³΄λ€ 1 - 2 - 3 (3 + 1) μ ν΅ν κ²½λ‘κ° λΉμ©μ΄ λ μ λ ΄ν κ²μ μ μ μμ΅λλ€.
μ΄ λ, μκ³ λ¦¬μ¦μμλ κΈ°μ‘΄μ μκ³ μλ 3
μΌλ‘ κ°λ μ΅μ λΉμ©μ 6μμ 4 λ‘ μλ‘ κ°±μ νκ² λ©λλ€.
μ΄λ κ² λ€μ΅μ€νΈλΌ μκ³ λ¦¬μ¦μ νμ¬κΉμ§ μκ³ μλ μ΅λ¨ κ²½λ‘λ₯Ό κ°±μ νλ©° λ
Έλ λ³ μ΅λ¨ κ²½λ‘λ₯Ό μ°Ύκ² λλλ°
μ΄λ¬ν μ°μ°μ relax
λΌ νλ©°, μ΄λ° μ°μ°μ νλ κ²μ relaxation
μ΄λΌ ν©λλ€.
π λ€μ΅μ€νΈλΌ μκ³ λ¦¬μ¦ λμ κ³Όμ
μμ κ·Έλνλ₯Ό ν΅ν΄ λ€μ΅μ€νΈλΌ μκ³ λ¦¬μ¦μ λμ κ³Όμ μ λν΄ μμΈν μ΄ν΄λ³΄κ² μ΅λλ€.
κ°μ€μΉλ κ°μ€μΉ μΈμ νλ ¬ μ΄λΌ λΆλ¦¬λ 2μ°¨μ λ°°μ΄μ μ μ₯ν©λλ€. μ΄λ μκΈ° μμ μ λν κ°μ€μΉλ 0μΌλ‘ νμν©λλ€. μκΈ° μμ μ λν κ°μ€μΉ κ°μ΄ 0 μΌλ‘ λνλ΄κΈ° λλ¬Έμ λ
Έλκ° κ°μ μ΄ μμμ λνλΌ λ λ 0 μ΄λΌλ κ° λμ 무νλ μ κ°μ μ¬μ©ν©λλ€.
λ€μ΅μ€νΈλΌ μκ³ λ¦¬μ¦μμλ μμ μ μ μμ μ§ν© 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
μΌλ‘ μ‘μλ€κ³ κ°μ ν΄λ΄
μλ€.
μ§ν© S
μλ μμμ μ μΈ 0
μ΄ λ€μ΄κ° μμ΅λλ€. λν distance
λ°°μ΄μλ μκΈ°μμ μ λΉμ©μ 0
μ΄λ©°
μ°κ²°λμ΄ μμ§ μλ μ μ λ€μ 무νλ
λ‘ νμλμ΄ μμ΅λλ€.
μ΄μ μ μ 0
μ μ
μ₯μμ κ°μ₯ 짧μ 거리μ μ μ μ μ°Ύμλ³΄κ² μ΅λλ€.
μ°μ κ°μ μ΄ μ§μ μ μΌλ‘ μ°κ²°λμ΄μμ§ μμμ λΉμ©μ΄ 무νλλ‘ νμλμ΄ μλ 2, 3, 6
μ΄ μ μΌ λ¨Όμ μ μΈλ©λλ€.
μ΄ ν, μΈμ μ μ μΈ 4, 1, 5
μ μ μ€ 3
μΌλ‘ κ°μ₯ μ μ λΉμ©μ κ°μ§κ³ μλ μ μ 4
κ° μ§ν© S
μ μΆκ°λ©λλ€.
μλ‘μ΄ μ μ μ΄ μ§ν© S
μ μΆκ° λμμΌλ―λ‘ λ€λ₯Έ μ μ λ€μ distance κ°
μ΄ λ³κ²½λ©λλ€.
μ μ 0
μμ κ°μ μ΄ μ΄μ΄μ Έμμ§ μμ 무νλλ‘ νμλμ΄μλ μ μ 3
κ³Ό 6
μ΄ μ μ 4
λ₯Ό ν΅ν΄μ μ κ·Όμ΄ κ°λ₯ν΄μ‘μΌλ―λ‘
κ°μ΄ μλ‘ λ³κ²½ λ©λλ€.
λν relax μ°μ°
μ ν΅ν΄ μ μ 1
μ distance κ°
μ΄ μ΅μκ°
μΌλ‘ κ°μ΄ λ³κ²½ λμμ΅λλ€.
λ€μμΌλ‘ μ§ν© S
μ μνμ§ μμ μ μ μ€ κ°μ₯ μ μ λΉμ©μ κ°μ§κ³ μλ μ μ 1
μ μ νν©λλ€.
μ μ 1
μ μ§ν© S
μ μλ‘ μΆκ°νκ³ λ§μ°¬κ°μ§λ‘ λ€λ₯Έ μ μ λ€μ distance κ°
μ μλ‘ λ³κ²½ν©λλ€.
μ μ 2
μ λν΄ μ μ 1
μ ν΅ν΄ μ κ·Όμ΄ κ°λ₯νκ² λμμΌλ―λ‘ relax μ°μ°
μ ν΅ν΄ κΈ°μ‘΄ 무νλμ κ°μμ 9λΌλ μ΅μκ°
μ μλ‘ λ³κ²½λμμ΅λλ€.
λ€μμΌλ‘ μ§ν© S
μ μνμ§ μμ μ μ μ€ κ°μ₯ μ μ λΉμ©μ κ°μ§κ³ μλ μ μ 6
μ μ ννμ¬ μλ‘ S
μ μΆκ°ν©λλ€.
μ§ν© S
μ μ μ 6
μ΄ μΆκ°λ¨μΌλ‘μ¨ μ μ 3
μ λν μ λ³΄κ° 14 β 12 λ‘ μλ‘ λ³κ²½λμμ΅λλ€.
(distance[3] = min(distance[3], distance[6] + weight(6, 3) = min(14, 8 + 4) = 12 )
λ€μμΌλ‘ μ§ν© S
μ μνμ§ μμ μ μ μ€ κ°μ μ μ λΉμ©μ κ°μ§κ³ μλ μ μ 2
λ₯Ό μ ννμ¬ μ§ν© S
μ μΆκ°ν΄μ€λλ€.
μ§ν© 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()
π μμ κ°μ μ΄ μ‘΄μ¬νκ² λ κ²½μ° λ€μ΅μ€νΈλΌ μκ³ λ¦¬μ¦μ μ¬μ©νμ§ μλ μ΄μ
- (κ°μ€μΉμ ν©μ΄ μμμΈ) μμ μ¬μ΄ν΄μ λ°μ κ°λ₯μ±
- μμμ μ 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 κ³μ°μ μ€λ₯ κ°λ₯μ±
- 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