๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Algorithm Study

์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜(๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜)

by DUSTIN KANG 2024. 4. 19.

๐ŸŒฑ ์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜

์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜(Shortestest Path)์€ ๊ฐ€์žฅ ์ ์€ ๋น„์šฉ(Minimum Cost)์œผ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฐ„์„ ๋“ค์„ ์ฐพ๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

๋Œ€ํ‘œ์ ์ธ ์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ๋กœ, ๋‹ค์ต์ŠคํŠธ๋ผ, ๋ฒจ๋งŒ-ํฌํŠธ, ํ”Œ๋กœ์ด๋“œ-์›Œ์…œ, A* ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜(Dijkstra) ์œ„์ฃผ๋กœ ๊ณต๋ถ€ํ•ด๋ณผ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.


๐Ÿš€ ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„ํ•˜๊ธฐ

๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์‹œ์ž‘๋…ธ๋“œ์—์„œ๋ถ€ํ„ฐ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค.

์ฒซ๋ฒˆ์งธ ๋ฌธ์ œ๋Š” ํŠน์ •๋…ธ๋“œ์—์„œ ๋ชจ๋“  ๋…ธ๋“œ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค - ๋ฐฐ๋‹ฌโ†— ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ํ†ตํ•ด ๋™์ž‘ ๋ฐฉ์‹์„ ์ดํ•ดํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

ํ•ด๋‹น ๋ฌธ์ œ๋Š” 1๋ฒˆ ๋…ธ๋“œ๋ถ€ํ„ฐ 5๋ฒˆ ๋…ธ๋“œ๊นŒ์ง€์˜ ๊ฐ„์„ ๊ณผ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๊ฐ€ ๋‹ด๊ธด ๋ฆฌ์ŠคํŠธ `road`์™€ ๋…ธ๋“œ์˜ ๊ฐฏ์ˆ˜ `N` ์ œํ•œ ๊ฒฝ๋กœ `K`๊ฐ€ ์ฃผ์–ด์ง€๋ฉด ์ œํ•œ ๊ฒฝ๋กœ ์•ˆ์— ์žˆ๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ์˜ ๋…ธ๋“œ์˜ ๊ฐฏ์ˆ˜๋ฅผ ์ฐพ๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. 

 

1. ๋จผ์ € ๋น„์šฉ ๋ฆฌ์ŠคํŠธ ๋งŒ๋“ค๊ธฐ

์ตœ๋‹จ ๊ฒฝ๋กœ ๋ฌธ์ œ์˜ ํฌ์ธํŠธ๋Š” ๋จผ์ € ๋ฐฉ๋ฌธ์—ฌ๋ถ€์™€ ๋น„์šฉ(Cost; Distance)๋ฅผ ํ™•์ธ๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฆฌ์ŠคํŠธ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด ๋น„์šฉ์„ ๊ณ„์‚ฐํ•˜๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค๊ณ  ์‹œ์ž‘ ๋…ธ๋“œ์—” 0์œผ๋กœ ๋Œ€์ž…ํ•˜๊ณ  ๋‚˜๋จธ์ง€์—” ์ตœ๋Œ“๊ฐ’์ธ `1e9` or (`float('inf')`)๋ฅผ ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค.

 

def solution(N, road, K):
    dist = [1e9] * (N+1)
    
    dist[1] = 0
    
    graph = [[] for _ in range(N+1)]
    for r in road:
        graph[r[0]].append([r[2], r[1]])
        graph[r[1]].append([r[2], r[0]])
        
    dijkstra(dist,graph)
    
    # ๊ฑฐ๋ฆฌ ์ค‘ K ์ดํ•˜์˜ ๋…ธ๋“œ์˜ ๊ฐฏ์ˆ˜ ๋ฐ˜ํ™˜ํ•˜๊ธฐ
    return len([i for i in dist if i <= K])

 

2. ๋ฐฉ๋ฌธ์„ ์œ„ํ•ด ์šฐ์„ ์ˆœ์œ„ ํ์‚ฌ์šฉํ•˜๊ธฐ

๋“œ๋””์–ด, ์ง€๊ธˆ๋ถ€ํ„ฐ ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ ์šฉํ•˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค.

๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ์ด์šฉํ•ด ๊ฐ€์žฅ ๊ฑฐ๋ฆฌ๊ฐ€ ์ž‘์€ ๊ฐ’๋ถ€ํ„ฐ ์ถ”์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์šฐ์„ ์ˆœ์œ„ ํ์— ๋Œ€ํ•œ ์ •๋ณด๋Š” ์šฐ์„ ์ˆœ์œ„ ํ ํฌ์ŠคํŠธโ†—์— ์ •๋ฆฌํ•ด๋‘์—ˆ์Šต๋‹ˆ๋‹ค. ํŒŒ์ด์ฌ์—์„œ๋Š” `heapq` ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

  1. ๋จผ์ € ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ํ†ตํ•ด ๊ฐ€์žฅ ๋น„์šฉ์ด ์ ์€ ์ •์ ์„ ๊บผ๋‚ด ํ˜„์žฌ ์ •์ (`node`)์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. (์ฒ˜์Œ์—” 1๋ฒˆ ๋…ธ๋“œ๊ฐ€ ํ˜„์žฌ ์ •์ ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.)
  2. ํ˜„์žฌ ์ •์ ๊ณผ ์ธ์ ‘ํ•œ ์ •์ ๋“ค์˜ cost ๊ฐ’์„ ๋น„๊ตํ•˜๋ฉด์„œ ์ตœ์†Œ๊ฐ’์„ ๊ฐฑ์‹ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.  (`cost + next_cost < dist[next_node]`)
  3. ๊ทธ ๋‹ค์Œ, ๊ฐฑ์‹ ์ด ๋˜์—ˆ๋‹ค๋ฉด ๊ฐฑ์‹ ๋œ ๋…ธ๋“œ(`next_node`)์— ๊ฐฑ์‹  ๊ฐ’์„ ๋„ฃ์–ด์ฃผ๊ณ  ๋‹ค์‹œ ํž™์— ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

1๋ฒˆ Node์˜ ์ธ์ ‘ํ•œ ๋…ธ๋“œ๋“ค์€ 2๋ฒˆ๊ณผ 4๋ฒˆ ์ž…๋‹ˆ๋‹ค.

 

2๋ฒˆ ๋…ธ๋“œ์˜ ์ธ์ ‘ ๋…ธ๋“œ์ธ 3๋ฒˆ๊ณผ 5๋ฒˆ์€ 1e9์™€ ๋น„๊ตํ•˜์—ฌ ์ตœ์†Œ๊ฐ’์„ ๊ฐฑ์‹ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

import heapq

def dijkstra(distance, graph):
    
    # ๋ฐฉ๋ฌธํ•  ๋…ธ๋“œ๊ฐ€ ์ €์žฅ๋  ์šฐ์„ ์ˆœ์œ„ ํ
    queue = []
    heapq.heappush(queue, [0, 1]) # ์‹œ์ž‘ ๋…ธ๋“œ๋ถ€ํ„ฐ ์‹œ์ž‘
    
    while queue:
        cost, node = heapq.heappop(queue) # 1
        
        # ์ด๋ฏธ ๋ฐฉ๋ฌธํ•œ ์ •์ ์˜ ๊ฒฝ์šฐ
        if distance[node] == 1e9:
            continue
        
        for next_cost, next_node in graph[node]:
            if cost + next_cost < dist[next_node]: # 2 
                distance[next_node] = cost + next_cost # 2
                heapq.heappush(queue, [cost + next_cost, next_node]) # 3

 

๐ŸŒฑ ์‹œ๊ฐ„ ๋ณต์žก๋„

๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜ 1๊ฐœ์˜ ๋…ธ๋“œ์—์„œ ์ธ์ ‘ํ•œ ๊ฐ„์„ ๋“ค์„ ๋ชจ๋‘ ๊ฒ€์‚ฌํ•˜๊ฒŒ๋ฉ๋‹ˆ๋‹ค.

๋˜, ๊ฐ„์„ ์„ ๊ฒ€์‚ฌํ•  ๋•Œ๋งˆ๋‹ค ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ํ†ตํ•ด ๋…ธ๋“œ ๋ฐ ๊ฑฐ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ณผ์ •์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๋ก ์ ์œผ๋กœ, ๊ฐ„์„ ์„ ๋ชจ๋‘ ๊ฒ€์‚ฌํ•˜๋Š” ๊ณผ์ •(`O(E)`)์™€ ๊ฑฐ๋ฆฌ ์ •๋ณด๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ณผ์ •(`O(log V)`)์„ ํ•ฉ์นœ ์‹œ๊ฐ„ ๋ณต์žก๋„ ์ž…๋‹ˆ๋‹ค.

์‹œ๊ฐ„ ๋ณต์žก๋„
O(E log V)

๐ŸŒฑ ์ด์™ธ ์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜

์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ๋Š” ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜๋งŒ ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ด์™ธ์—๋„ ํ”Œ๋กœ์ด๋“œ-์›Œ์…œ ์•Œ๊ณ ๋ฆฌ์ฆ˜, A* ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํ”Œ๋กœ์ด๋“œ ์›Œ์…œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ : 3์ค‘ ๋ฐ˜๋ณต๋ฌธ์„ ์ด์šฉํ•ด ๋ชจ๋“  ๋…ธ๋“œ์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค. 
  • A* ์•Œ๊ณ ๋ฆฌ์ฆ˜ : ํœด๋ฆฌ์Šคํ‹ฑ ํ•จ์ˆ˜(ํ‰๊ฐ€ ํ•จ์ˆ˜)๋ฅผ ํ†ตํ•ด ์ถ”์ •๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ž…๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” ํœด๋ฆฌ์Šคํ‹ฑ ํ•จ์ˆ˜์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€์ง€๋งŒ ์ตœ์„  O(E)์˜ ์‹œ๊ฐ„์— ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. 
  • ๋ฒจ๋งŒ ํฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ : ์Œ์˜ ๊ฐ€์ค‘์น˜๊ฐ€ ์žˆ๋Š” ๊ทธ๋ž˜ํ”„์—์„œ๋„ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ํŠน์ง•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(V * E) ์ž…๋‹ˆ๋‹ค. 

A*๋Š” ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ฐœ์„ ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค.

๐Ÿ“ ํ’€์–ด๋ณด๊ธฐ ์ข‹์€ ๋ฌธ์ œ๋“ค


โ˜•๏ธ ํฌ์ŠคํŒ…์ด ๋„์›€์ด ๋˜์—ˆ๋˜ ์ž๋ฃŒ

์˜ค๋Š˜๋„ ์ €์˜ ํฌ์ŠคํŠธ๋ฅผ ์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์„ค๋ช…์ด ๋ถ€์กฑํ•˜๊ฑฐ๋‚˜ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๊ฑฐ๋‚˜ ์ž˜๋ชป๋œ ๋ถ€๋ถ„์ด ์žˆ์œผ๋ฉด ๋ถ€๋‹ด์—†์ด ๋Œ“๊ธ€๋กœ ๋‚จ๊ฒจ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.