교재 : 파이썬으로 배우는 자료구조 프로그래밍 (유석종, 휴먼싸이언스)
10.1 최단 경로 탐색 (shortest path finding)
1) 최단 경로 탐색
- 그래프의대표적인 문제 중 하나
- 탐욕 알고리즘, 다익스트라 알고리즘, 플로이드-와샬 알고리즘 등이 있음.
2) 탐욕 알고리즘 (Greedy algorithm)
- 출발지에서 최소 비용 간선만을 포함하여 미 방문 노드로 이동하는 경로 탐색 방법
- 목적지에 도달할 때까지 위 과정을 반복한다.
- 매 순간 최적이라고 판단하는 것을 반복적으로 선택한다.
- 지역적인 해(local solution)를 제공해줄 수 있지만, 전역적인 해(global solution)를 보장하지는 않는다.
3) 다익스트라 알고리즘 (Dijkstra)
- 노드 간의 최단 경로를 찾기 위해서는 출발 노드에서 각 노드에 이르는 모든 최단 경로를 탐색한다.
- n개의 정점이 존재할 때 각 노드로의 n개 최단 경로를 비용이 증가하는 순서로 생성한다.
- 간선의 비용은 음수가 아니라고 가정한다.
- 알고리즘
- 출발 정점도 하나의경로이며 비용은 0이다.
- 현재까지 발견된 경로에 인접 간선을 1개 추가하여 기존 경로 비용보다 큰 값 중 최소인 최단 경로를 찾는다.
- 모든 노드에 이르는 최단 경로를 찾을 때까지 2번 과정을 반복한다.
- 코드
class Node:
def __init__(self, node, weight):
self.data = node
self.weight = weight
class ShortestPath:
def __init__(self):
self.graph = {}
self.visit = []
self.dist = {}
self.prev = []
self.min_list = []
def create(self, v, dest, weight):
node = Node(dest, weight)
if v not in self.graph:
self.graph[v] = []
self.graph[v].append(node)
def dijkstra(self,v):
if v not in self.visit:
self.visit[v] = {}
else:
return
if v not in self.graph:
print("End of Search")
return
for node in self.graph[v]:
vertex = node.data
cost = node.weight
if vertex not in self.dist or cost + self.visit[v] < self.dist[vertex]:
self.dist[vertex] = cost + self.dist[v]
self.prev[vertex] = v
self.min_list[vertex] = cost + self.dist[v]
self.view_array()
v = self.pick_min_dist()
self.dijkstra()
def view_array(self):
print('dist', sorted(self.dist.items()))
print('prev', sorted(self.prev.items()))
def pick_min_dist(self):
temp = []
for v, cost in self.min_list.items():
temp.append((cost,v))
temp = sorted(temp)
cost, v = temp.pop(0)
print('Next min cost vertex is', v)
self.min_list.pop(v)
return v
def show(self):
for no, alist in self.graph.items():
print('[', no, ']', end=' ')
for node in alist:
print('(', node.data, node.weight, ')', end=' ')
print()
10.2 플로이드-와샬 알고리즘 (Floyd-warshell)
1) 플로이드-와샬 알고리즘
- 간선에 비용이 있는 방향 그래프에서 모든 정점 간 경로를 탐색하는 방법
- 비용 행렬(cost matrix: A-1)
- 각 원소(A-1[i][j])에 두 정점 i, j 사이의 간선 비용이 저장되어 있는 행렬
- A-1[i][j] = weight(i, j)
- 정점 사이가 간선으로 연결되지 않은 경우 무한대 값을 저장한다.
- 비용 행렬 Ak의원소 Ak[i][j]에는 정점 k를 거쳐 정점 i에서 j로 가는 최단 경로 비용이 저장되어 있다.
- Ak[i][j] = min(Ak-1[i][j], Ak-1[i][k] + Ak-1[k][j]), k ≥ 0
2) 이행적 폐쇄 행렬 (transitive closure matrix : A+)
- 두 노드 사이의 경로 존재 유무를 행렬로 표현한 것
- 행렬의 원소는 두 노드 간 경로가 존재하면 1, 존재하지 않으면 0이다.
3) 반사 이행적 폐쇄 행렬 (reflexive transitive closure matrix : A*)
- 자기 자신으로 가는 경로로 허용하며 이행적 폐쇄 행렬의 대각선 원소 값을 1로 지정한다.
10.3 작업 네트워크와 위상정렬
1) 작업 네트워크 (Activity network)
- 그래프의 정점 또는 간선에 작업을 표시하여 작업의 선수 관계를 표시하는 네트워크
- 정점 작업 네트워크와 간선 작업 네트워크로 나뉜다.
2) 정점 작업 네트워크
: 프로젝트 수행에 필요한 작업들 간에 선수 관계를 표시한 네트워크
3) 위상 정렬 (topology sort)
- 사이클이 없는 방향 그래프(directed acyclic graph : DAG)에서 작업들을 선수 관계에 의해 정렬하는것
- 인접 리스트로 표현된 그래프에서 위상정렬의 시간복잡도는 O(n+e)이다.
- 큐를 이용해 구현한다.
- 알고리즘
- 차수가 0인 정점(작업)을 큐(queue)에 넣는다.
- 큐애서 정점을 제거하고 이 정점에 연결된 간선들을 삭제한다.
- 모든 정점을 방문하였으면 종료하고 그렇지 않으면 과정 1부터 반복한다.
- 빈 큐 상태에서 정점을 제거하려고 하면, 그래프에 사이클이 존재한다는 오류를 출력하고 종료한다.
10.4 간선 작업 네트워크
1) 간선 작업 네트워크 (Activity on Edge network : AOE)
- 프로젝트 수행을 위한 작업(A)를 간선(edge)에 표시하고, 공정(V)은 정점(vertex)으로 나타낸 그래프이다.
- 특정 정점으로 들어오는 작업들이 모두 완료되어야 해당 공정을 시작할 수 있다.
- 전체 프로젝트 완료 시간에 영향을 미치는 작업들을 탐색하고 공정의 선수 관계를 분석하는 데 활용한다.
- 각 작업의 최단 시작 시간, 최장 시작 시간을 계산할 수 있다.
- 임계도(criticaliy)
- 작업의 여유 시간(slack)을 의미하는 것
- L(i) - E(i)
- 임계 작업(critical activity) : 임계도가 0인 작업으로, 전체 프로젝트 수행 시간에 영향을 미치는 작업
2) 최단 시작 시간 (earlist star time : E)
- 작업 Ai를 가장 빨리 시작할 수 있는 시간 : E(i)
3) 최장 시작 시간 (Latest start time : L)
- 프로젝트를 지연시키지 않으면서 작업 Ai를가장늦게 시작할 수 있는시간 : L(i)
'전공과목 정리 > 자료구조' 카테고리의 다른 글
[자료구조💾] 12장 탐색 트리 (0) | 2024.01.26 |
---|---|
[자료구조💾] 11장 탐색과 해싱 (4) | 2024.01.25 |
[자료구조💾] 9장 그래프 (2) | 2024.01.23 |
[자료구조💾] 8장 정렬 (4) | 2024.01.21 |
[자료구조💾] 7장 최대 힙 (0) | 2024.01.20 |