<<Graph>>
연결되어 있는 원소들 사이의 다:다 관계를 표현하는 비선형 자료구조
Graph G - 2개의 집합 v(vertax)와 e(edge)로 구성
V: 공집합이 아닌 정점의 유한집합
E: 간선이라고 하는 정점 쌍들의 집합
표기: G = (V, E)
* Graph 종류
무(방)향 그래프(undirected graph)
두 정점을 연결하는 간선에 방향이 없는 그래프
간선을 나타내는 쌍에 순서 없음
간선을 통해서 양방향으로 갈 수 있음
방향 그래프(directed graph)
모든 간선은 방향을 가짐
방향은 정점의 쌍 <u, v>정점의 순서로 표시. (u -> v)
부분 그래프(sub graph)
원래의 그래프에서 정점이나 간선을 일부만 제외하여 만든 그래프
가중 그래프(weighted graph) or network
정점을 연결하는 간선에 가중치를 할당한 그래프
* Graph 용어
인접정점(adjacent vertax) : 하나의 정점에서 간선에 의해 직접 연결된 정점 B->D (o), B<-C (x)
방향 그래프의 차수: 진입 차수, 진출 차수
무방향 그래프의 차수 : 모든 간선 수 * 2
정점 u로부터 정점 v까지의 경로(path): u에서 v까지 간선을 따라 갈 수 있는 정점을 순서대로 나열한 것
경로의 길이: 경로 상에 있는 간선의 수
단순 경로: 경로중에 반복되는 간선이 없는 경로
사이클: 시작정점과 종료 정점이 동일한 단순 경로
DAG(direvted acyclic graph): 방향그래프이면서 사이클이 없는 그래프
*그래프 연결정도
연결그래프(connected graph): 모든 정점 쌍에 대하여 항상 경로 존재하는 무방향 그래프
*tree : 사이클을 가지지 않는 연결 그래프
단절그래프: 연결되지 않은 정점이 있는 그래프
연결요소: 최대 연결 부분 그래프
완전그래프: 모든 정점이 연결되어 있는 그래프
강력 연결 : 방향그래프에서 서로다른 두 정점 u, v의 모든 쌍에 대해 u에서 v로 v에서 u로의 방향 경로 존재
강력 연결 요소: 강력 연결된 최대 부분 그래프
약한 연결 : u에서 v로 또는 v에서 u로의 어느 하나의 경로만 존재
<graph의 표현>
1. 인접 행렬(adjacent matrix)
행렬에 대한 2차원 배열을 사용하는 순차 자료구조 방법
그래프의 두 정점을 연결한 간선의 유무를 행렬로 저장
인접행렬의 대각선 성분은 모두 0
2. 인접 리스트(adjacent list)
연결 자료구조를 이용하며 각 정점에 대한 인정 정점들을 연결하여 만든 단순 연결리스트
<graph traversal>
하나의 정점에서 시작하여 모든 정점을 한 번씩 방문하여 처리하는 연산
Ex) 도로망에서 특정 도시에서 다른 도시로 갈 수 있는지 여부
그래프 탐색방법: 깊이 우선 탐색, 넓이 우선 탐색
1. 깊이 우선 탐색 원리 (스택 사용)
하나의 정점 방문 -> 이웃한 정점으로 갈 수 잇으면 무조건 이웃 중 하나로 방문(push) (과거에 방문하지 않은 정점이어야 함) -> 반복 -> 만약 방문 가능한 이웃 정점이 없다면 (pop) 왔던 경로 상의 가장 최근에 방문했던 정점으로 돌아가서 그 정점 이웃 노드 방문을 시도
2. 너비 우선 탐색 원리 (큐 사용)
시작정점 v를 방문 -> v에 인접한 모든 정점들을 방문(enqueue) ->모두 찾았으면 앞에부터 dequeue하며 새롭게 방문한 정점들에 인접하면서 아직 방문하지 못한 정점들을 방문 -> 반복 -> 큐가 공백이면 탐색 종료
<<Spanning Tree>>
그래프 G의 신장 트리
조건: G는 연결 그래프
정의: G의 spanning tree는 G의 모든 정점들이 포함되어야 하며 연결 그래프이고 acyclic
*n개 정점의 그래프의 신장트리는 n-1개의 간선을 가짐
신장트리 구하는 방법: 깊이 우선 신장트리. 너비 우선 신장트리
<최소 비용 신장 트리>
무방향 가중치 그래프에서 최저의 비용을 갖는 신장트리(간선들의 가중치 합이 최소)
최소 비용 신장 트리를 만드는 알고리즘: Kruskal, Prim algorithm
신장트리를 만드는 제한 조건:
그래프 내에 있는 간선들만을 사용
정확하게 n-1개의 간선만을 사용
사이클을 생성하는 간선 사용금지
<Kruskal Algorithm 1>
정의: 가중치가 높은 간선을 제거하면서 최소 비용 신장 트리를 만드는 방법
그래프 G의 모든 간선을 가중치에 따라 내림차순으로 정렬 -> 그래프 G에서 가중치가 가장 높은 간선 제거, disconnceted로 만드는 간선은 생략 -> 그래프에 간선이 n-1개만 남을 때까지 반복
<Kruskal Algorithm 2>
정의: 가중치가 낮은 간선을 삽입하면서 최소 비용 신장 트리를 만드는 방법
그래프 G의 모든 간선을 가중치에 따라 오름차순으로 정렬 -> 그래프 G에서 가중치가 가장 낮은 간선 삽입, 사이클을 형성하는 간선은 생략 -> 그래프에 간선이 n-1개가 삽입 될 때까지 반복
<Prim Algorighm>
정의: 간선을 정렬하지 않고 하나의 정점에서 시작하여 트리를 확장해나감
그래프 G의 시작 정점 선택 -> 선택한 정점에 부속된 모든 간선 중에서 가중치가 가장 낮은 간선을 연결하여 트리 확장 -> 이전에 선택한 정점과 새로 확장된 정점에 부속된 간선 중 가장 가중치가 낮은 간선 삽입, 단 사이클을 형성하는 간선은 생략 -> G에 n-1개 간선 삽입 될 때까지 반복
<<최단 경로 알고리즘>>
신장 트리가 아닌 가중치 그래프, 즉 네트워크에서 정점 u와 정점 v를 연결하는 경로 중에서 가중치 합이 최소인 경로
*Weight Adjacent Matrix
최단 경로를 구하려는 가중치 그래프의 가중치를 저장
간선 (i, j)가 그래프에 존재하면 M[i][j] = 가중치 값, 그래프에 존재하지 않으면 M[i][j] = 무한대
<Dijkstra Algorithm>
무방향, 방향 모두 적용 가능
가정 : 모든 간선은 음이 아닌 수
기능 : 시작 정점으로부터 다른 모든 정점까지의 최단 경로를 구한다
컨셉 : 시작 정점 v에서부터 정점 u까지 최단 경로 dist[u]를 구해 정점 u가 집합 S에 추가되면 새로 추가된 정점 u에 의해 단추고디는 경로가 있는지를 확인함, 현재 알고 있는 dist[w]와 새로 추가한 정점 u를 거쳐서 가는 dist[u] + cost[u][w]를 계산한 경로를 비교해 경로가 단축되면 dist[w]를 단축된 경로값으로 수정함으로써 최단경로를 찾음
<Bellman-Ford Algorithm>
그래프에서 정점 S에서 정점 G로 가는 최단경로?
특징 : 음수 비용을 허용하는 최단 경로 알고리즘
모든 vertax는 모든 간선에 대해서 relaxation 수행
<Floyd-Warshall Algorithm>
모든 정점의 쌍 u와 v간의 최단 경로를 구하는 알고리즘
모든 vertax에 대해 해당 vertax를 거쳐서 가는 최단경로를 구함