가장 적은 구간을 지나는 경로가 아닌, 가장 빠른 경로를 찾고 싶을 때 사용.
다익스트라 알고리즘의 4단계
가장 가격이 싼 정점 찾기. (=도달하는 데 시간이 가장 적게 걸리는 정점)
그 정점의 이웃 정점들의 가격을 조사함
정점의 가격 = 그 정점에 도달하는 데 필요한 것 (시간, 돈.. 등등)
만약 현재 가격보다 더 싼 경로가 존재한다면, 가격을 수정함
그래프 상 모든 정점에 대해 1,2를 반복
최종 경로를 계산
그래프의 각 간선이 가지는 숫자.
가중치를 가지는 그래프
가중치가 없는 그래프
그래프가 어떤 정점에서 출발해, 한 바퀴 돌아 같은 정점에서 끝날 때 사이클이 있다고 표현.
사이클을 지나면 최단 경로를 얻을 수 없다.
※ 무방향 그래프 (-
로 연결된 정점) 는 두 정점이 서로를 향햐고 있는 것, 즉 사이클을 의미한다.
해당 정점이 직전에 지나온 정점이 부모 정점이 된다.
다익스트라 알고리즘에서는 어떤 정점을 이미 처리하고 나면, 그 정점에 도달하는 더 싼 경로는 없다고 가정해 버림.
따라서 음의 가중치를 가진 간선이 있으면 다익스트라 알고리즘을 사용할 수 없다.
(대신, 벨만-포드 알고리즘을 사용하면 음의 가중치가 있어도 최단 경로를 찾을 수 있다.)
3개의 해시 테이블(그래프 해시 테이블, 가격 해시 테이블, 부모 해시 테이블) 그리고 한 개의 배열(처리한 정점 추적)이 필요하다
그래프 해시 테이블
graph= {}
graph["start"] = {} # 시작점의 이웃 정점과 그 가격
graph["start"]["a"] = 6
graph["start"]["b"] = 2
graph["a"] = {} ## 정점 a의 이웃 정점과 그 가격
graph["a"]["fin"] = 1
graph["b"] = {} ## 정점 b의 이웃 정점과 그 가격
graph["b"]["a"] = 3
graph["b"]["fin"] = 5
graph["fin"] = {} ## 도착점 (이웃이 없음)
가격 해시 테이블
∞
)로 저장한다.infinity = float("inf")
costs = {}
costs["a"] = 6
costs["b"] = 2
costs["fin"] = infinity
부모 해시 테이블
parents = {}
parents["a"] = "start"
parents["b"] = "start"
parents["fin"] = None
정점 추적 배열
processed = []
def find_lowest_cost_node(costs): ## 가장 가격이 싼 정점을 찾는 메서드
lowest_cost = float("inf")
lowest_cost_node = None
for node in costs: ## 가격 테이블의 모든 정점 확인
cost = costs[node] ## 아직 처리하지 않은 정점 중 더 싼 것이 있으면
if cost < lowest_cost and node not in processed:
lowest_cost = cost ## 그 정점을 새로운 최저 정점으로 설정
lowest_cost_node = node
return lowest_cost_node
node = find_lowest_cost_node(costs) ## 아직 처리하지 않은 가장 싼 정점 찾기
while node is not None: ## 모든 정점 처리 시 반복문 종료
cost = costs[node] ## 노드의 가격
neighbors = graph[node] ## 이웃(해시 테이블 객체)
for n in neighbors.keys(): ## 노드의 이웃 정점들 탐색
new_cost = cost + neighbors[n]
if costs[n] > new_cost: ## 만약 이 정점을 지나는 것이 가격이 더 싸다면 (더 빠르다면)
costs[n] = new_cost ## 해당 정점의 가격 갱신
parents[n] = node ## 부모 정점 갱신
processed.append(node) ## 정점을 처리한 것을 기록
node = find_lowest_cost_node(costs) ## 다음으로 처리할 정점을 찾아 반복