1 / 69

자료구조

자료구조. 제 6 장 그래프. 6.1 그래프 추상 데이타 타입. 6.1 그래프 추상 데이타 타입. ▶ 개요 - Koenigsberg 다리 문제 - 차수 (degree) : 정점에 연결된 간선의 수 - 오일러 행로 (Eulerian walk) 그림 6.1: (a) Koenigsberg 의 Pregal 강의 일부 (b) Euler 의 그래프. 6.1 그래프 추상 데이타 타입. ▶ 정의 - 그래프 G : 2 개의 집합 V 와 E 로 구성

erasto
Download Presentation

자료구조

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 자료구조 제 6 장 그래프

  2. 6.1 그래프 추상 데이타 타입

  3. 6.1 그래프 추상 데이타 타입 • ▶ 개요 • - Koenigsberg 다리 문제 • - 차수(degree) : 정점에 연결된 간선의 수 • - 오일러 행로(Eulerian walk) • 그림 6.1: (a) Koenigsberg의 Pregal강의 일부 • (b) Euler의 그래프

  4. 6.1 그래프 추상 데이타 타입 • ▶ 정의 • - 그래프 G : 2개의 집합 V와 E로 구성 • •V : 공집합이 아닌 정점(vertices)의 유한집합 • •G : 간선(edges)의 집합 • •표기 : G=(V,E) • - 무방향그래프(undirected graph) • •간선을 나타내는 정점의 쌍에 순서 없음 • - 방향 그래프(directed graph) • •간선을 나타내는 정점의 쌍에 순서 있음 • •간선 : 방향을 가지는 정점의 쌍 <u,v>로 표시 • (u는 꼬리(tail), v는 머리(head)) • 그림 6.2: 세개의 예제 그래프

  5. 6.1 그래프 추상 데이타 타입 • - 그래프의 제한 사항 • (1) 자기 간선(self edge) 또는 자기 루프(self loop) 없음 • (2) 동일 간선의 중복 없음 • (다중그래프(multigraph)는 이 제한이 없음) • 그림 6.3: 그래프 형태 구조의 예 • - 완전 그래프(complete graph) • : n개의 정점과 n(n-1)/2개의 간선을 가진 그래프 - (u,v)가 E(G)의 한 간선이라면 • u와 v는 인접(adjacent)한다 • •간선 (u,v)는 정점 u와 v에 부속(incident)된다 • - 그래프 G의 부분그래프(subgraph) • : V(G')⊆V(G)이고 E(G')⊆E(G)인 그래프 G'

  6. 6.1 그래프 추상 데이타 타입 • 정점 u로부터 정점 v까지의 경로(path) : 그래프 G에서 (u,i1), (i1,i2), ..., (ik,v)를 E(G)에 속한 간선들이라 할 때, 정점열 u, i1, i2, ..., ik, v를 말함 • - 경로의 길이(length) : 경로상에 있는 간선의 수 • - 단순 경로(simple path) • : 경로상에서 처음과 마지막을 제외한 모든 정점들이 • 서로 다름 • - 단순 방향 경로(simple directed path) • - 사이클(cycle) • : 처음과 마지막 정점이 같은 단순 경로 • 그림 6.4: 부분그래프

  7. 6.1 그래프 추상 데이타 타입 • - 연결요소(connected component) • :최대연결부분그래프(maximalconnected subgraph) • - 강력 연결(strongly connected) • : 방향그래프에서 V(G)에 속한 서로 다른 두 정점 u, v • 의 모든 쌍에 대해서, u에서 v로, 또한 v에서 u로의 • 방향 경로(directed path)가 존재 • - 강력 연결요소(strongly connected component) • : 강하게 연결된 최대 부분그래프 • 그림 6.5: 두 개의 연결요소를 갖는 그래프

  8. 6.1 그래프 추상 데이타 타입 • 그림 6.6: G3의 강력 연결요소 • - 차수(degree) : 정점에 부속한 간선들의 수 • - 진입차수(in-degree) • : 임의의 정점 v가 머리가 되는 간선들의 수 • - 진출차수(out-degree) • : v가 꼬리가 되는 간선들의 수 • - 간선의 수 • (n개의 정점, e개의 간선, 정점 i의 차수를 di) • - 다이그래프(digraph) : 방향 그래프

  9. 6.1 그래프 추상 데이타 타입 • ----------------------------------------- • classGraph • { • // objects:공집합이 아닌 정점의 집합과 무방향 간선의 집 • //합으로각 간선은 정점의 쌍임. • public: • Graph(); • // 하나의 공백 그래프를 생성 • voidInsertVertex(Vertex v); • // v를 그래프에 삽입; v는 부속한 간선을 갖지 않음 • voidInsertEdge(Vertex u, Vertex v); • // 간선 (u,v)를 그래프에 삽입 • voidDeleteVertex(Vertex v); • // v와 v에 부속된 모든 간선들을 삭제 • voidDeleteEdge(Vertex u, Vertex v); • // 간선 (u,v)를 그래프에서 삭제 • Boolean IsEmpty(graph); • // if그래프에 정점이 없음 returnTRUE (1); • // else returnFALSE (0); • List<Vertex> Adjacent(Vertex v); • // v에 인접한 모든 정점들의 리스트를 반환 • }; • ----------------------------------------- • ADT6.1: 그래프 추상 데이타 타입

  10. 6.1 그래프 추상 데이타 타입 • ▶ 그래프 표현법 • - 인접행렬 (Adjacency Matrix) • •G=(V,E)는 정점의 수가 n(n≥1)인 그래프 • •인접행렬 : n×n의 2차원 배열 • •간선 (vi, vj) E(G) A[i][j]=1 • •간선 (vi, vj) E(G) A[i][j]=0 • •필요 공간 : n2비트 • 그림 6.7: 인접행렬 • •무방향그래프 • : 어떤 정점 i의 차수는 그 행의 합 • •방향그래프 • : 행의 합은 진출차수, 열의 합은 진입차수 • •인접행렬의 수행 시간 : 최소한 O(n2) • •희소 그래프(sparse graph) : O(e+n)

  11. 6.1 그래프 추상 데이타 타입 • - 인접리스트 (Adjacency Lists) • •인접행렬의 n행들을 n개의 연결리스트로 표현 • •data와 link 필드 • •C++ 선언문 • class Graph • { • private: • List<int> *HeadNodes; • int n; • public: • Graph(const int vertices = 0) : n(vertices) • { HeadNodes = new List<int>[n]; }; • }; • •n개의 정점, e개의 간선의 무방향그래프 • : n개의 헤드노드, 2e개의 리스트 노드가 필요 • •방향그래프 : e개의 리스트 노드 • •역인접리스트(inverse adjacency lists) • : 리스트가 표현하는 정점에 인접한 각 정점에 대해 • 하나의 노드를 둠

  12. 6.1 그래프 추상 데이타 타입 • 그림 6.8: 인접리스트

  13. 6.1 그래프 추상 데이타 타입 • 그림 6.9: 그래프 G4의 순차적인 표현 • 그림 6.10: G3(그림 6.2(c))의 역인접리스트

  14. 6.1 그래프 추상 데이타 타입 • 그림 6.11: 그림 6.2(c)의 그래프 G3의 직교 리스트 표현

  15. 6.1 그래프 추상 데이타 타입 • - 인접다중리스트 (Adjacency Multilists) • •간선 (u,v)는 두 개의 엔트리로 표현 • : u를 위한 리스트, v를 위한 리스트에 나타남 • •새로운 노드 구조 • •C++ 선언문 • enumBoolean FALSE,TRUE; • class Graph; // 전방 선언 • class GraphEdge { • friend Graph; • private: • Boolean m; int vertex1, vertex2; GraphEdge*path1, *path2; • }; • typedefGraphEdge*EdgePtr; • class Graph { • private: • EdgePtr*HeadNodes;int n; • public: • Graph(constint); • }; // 헤드 노드 배열을 설정 • Graph::Graph(constint vertices = 0) : n(vertices){ • HeadNodes= new EdgePtr[n]; • for (int i=0; i<n; i++) HeadNodes[i]=0; • }

  16. 6.1 그래프 추상 데이타 타입 • 그림 6.12: 그림 6.2(a)의 G1에 대한 인접다중리스트 • - 가중치 간선 (Weighted Edges) • • 그래프의 간선에 가중치(weights) 부여 • • 인접행렬 : 항 A[i][j]에 가중치 정보 저장 • • 인접리스트 : 노드 구조에 weight 필드를 추가 • • 네트워크(network) : 가중치 간선을 가진 그래프

  17. 6.2 기본적인 그래프 연산

  18. 6.2 기본적인 그래프 연산 • ▶ 깊이 우선 탐색 • - 깊이 우선 탐색(DFS; Depth First Search) • ⑴ 출발 정점 v를 방문 • ⑵ v에 인접하고 방문하지 않은 한 정점 w를 선택 • ⑶ w를 시작점으로 다시 깊이 우선 탐색 시작 • ⑷ 모든 인접 정점을 방문한 정점 u에 도달하면, 최근에 방문한 정점 중 아직 방문을 안한 정점 w와 인접하고 있는 정점으로 되돌아감 • ⑸ 정점 w로부터 다시 깊이 우선 탐색 시작 • ⑹ 방문이 된 정점들로부터 방문이 안된 정점으로 더 이상 갈 수 없을 때 종료

  19. 6.2 기본적인 그래프 연산 • ----------------------------------------- • voidGraph::DFS() // 드라이버 • { • visited = newBoolean[n]; • // visited를 Graph의 Boolean* 데이타 멤버로 선언. • for(inti=0; i<n; i++) visited[i] = FALSE; • // 초기에는 방문된 정점이 없음 • DFS(0); // 정점 0에서 탐색을 시작 • delete[] visited; • } • voidGraph::DFS(constintv) // 실제 탐색 수행 • // 정점 v에서 도달 가능하면서 아직 방문되지 않은 모든 • //정점들을 방문 • { • visited[v] = TRUE; • for(v에 인접한 각 정점 w에 대해) • // 실제 코드는 그래프 표현 방법에 좌우됨 • if(!visited[w]) DFS(w); • } • ----------------------------------------- • 프로그램 6.1: 깊이 우선 탐색

  20. 6.2 기본적인 그래프 연산 • - 예제 6.1 • •0, 1, 3, 7, 4, 5, 2, 6 순으로 방문 • 그림 6.16: 그래프 G와 그 인접리스트 • - DFS의 분석 • •탐색을 끝내는 시간 O(e) • •v에 인접한 모든 정점들을 찾는데 O(n)의 시간 • •총 시간은 O(n2)

  21. 6.2 기본적인 그래프 연산 • ▶ 너비 우선 탐색 • - 너비 우선 탐색(BFS; Breath First Search) • ⑴ 시작 정점 v를 방문 • ⑵ v에 인접한 모든 정점들을 방문 • ⑶ 새롭게 방문한 정점들에 인접하면서 아직 방문하지 못한 정점들을 방문 • - 예제 6.2 • • 0, 1, 2, 3, 4, 5, 6, 7 순으로 방문

  22. 6.2 기본적인 그래프 연산 • ----------------------------------------- • voidGraph::BFS(intv) • // 정점 v에서 시작하여 너비 우선 탐색을 수행.v 방문시 • //visited[i]는 TRUE가 됨. 이 알고리즘은 큐를 사용함 • { • visited = newBoolean[n]; • // visited를 Graph의 Boolean* 데이타 멤버로 선언. • for(inti=0; i<n; i++) visited[i] = FALSE; • // 초기에는 방문한 정점이 없음 • visited[v] = TRUE; • Queue<int> q; // q는 큐임 • q.Insert(v); // 정점을 큐에 삽입 • while(!q.IsEmpty()) { • v = *q.Delete(v); // 정점 v를 큐에서 삭제 • for(v에 인접한 모든 정점 w에 대해) • // 실제 코드는 그래프 표현 방법에 좌우됨 • if(!visited[w]) { • q.Insert(w); • visited[w] = TRUE; • } • }// while루프의 끝 • delete[] visited; • } • ----------------------------------------- • 프로그램 6.2: 너비 우선 탐색

  23. 6.2 기본적인 그래프 연산 • - BFS의 분석 • •전체 시간 O(n2) • •인접 리스트 표현 : 전체 비용 O(e)

  24. 6.2 기본적인 그래프 연산 • ▶ 연결요소 • - 연결요소(connected component) • : 방문하지 않은 정점 v에 대해 DFS(v) 또는 BFS(v)를 반복 호출로 구함 • ----------------------------------------- • voidGraph::Components() { • // 그래프의 연결요소들을 결정. visited는 Graph의 • // Boolean* 데이타 멤버로 선언되는 것으로 가정. • visited = newBoolean[n]; • for(inti=0; i<n; i++) visited[i] = FALSE; • for(i=0; i<n; i++) • if(!visited[i]) { • DFS(i); // 하나의 요소를 발견 • OutputNewComponent(); • } • delete[] visited; • } • ----------------------------------------- • 프로그램 6.3: 연결요소의 결정 • - Components의 분석 • •인접리스트로 표현 • : 모든 연결요소들 생성 시간은 O(n+e) • •인접행렬로 표현 : O(n2)

  25. 6.2 기본적인 그래프 연산 • ▶ 신장트리 • - 신장트리(spanning tree) : G의 간선들로만 구성되고 G의 모든 정점들이 포함된 트리 • •깊이우선 신장트리(depth first spanning tree) • •너비우선 신장트리(breath first spanning tree) • 그림 6.17: 완전 그래프와 이 그래프의 세 신장트리 • 그림 6.18: 그림 6.16의 그래프에 대한 깊이우선 및 • 너비우선 신장트리

  26. 6.2 기본적인 그래프 연산 • - 예제 6.3 [회로 등식의 생성] • ⑴ 전기 네트워크에 대한 신장트리 구함 • ⑵ 비트리 간선을 신장트리에 한번에 하나씩 도입 • ⑶ Kirchoff의 제 2 법칙 이용하여 회로 등식 얻음 • -신장트리는G의최소부분그래프(minimal subgraph) G'로서 V(G') = V(G)이고 G'는 연결되어 있음 • - 신장트리는 n-1개의 간선 가짐

  27. 6.2 기본적인 그래프 연산 • ▶ 이중결합요소 • - 단절점(articulation point) • : 그래프 G의 정점들중 이 정점과 이 정점에 부속한 모든 간선들 삭제시, 최소한 두개의 연결요소를 갖는 그래프 G'가 되게 하는 정점 v • 그림 6.19: 연결 그래프와 이중결합요소들 • - 이중결합그래프(biconnected graph) • : 단절점이 없는 연결 그래프 • - 이중결합요소(biconnected component) • : 최대이중결합부분그래프(maximal biconnected subgraph) H

  28. 6.2 기본적인 그래프 연산 • 그림 6.20: 그림 6.19(a)의 깊이우선 신장트리 • - 백 간선(back edge) : u가 v의 조상이거나 v가 u의 조상인 비트리 간선 (u,v) • - 교차 간선(cross edge) : 백 간선이 아닌 비트리 간선 • - low(w) : w의 후손들과 많아야 하나의 백 간선으로 된 경로를 이용해 w로부터 도달할 수 있는 가장 적은 깊이우선번호 • low(w) = mindfn(w), minlow(x) | x는 w의 자식, • mindfn(x) | (w,x)는 백 간선

  29. 6.2 기본적인 그래프 연산 • 그림 6.21: 그림 6.20(b)의 신장 트리에 대한 dfn값과 low값

  30. 6.2 기본적인 그래프 연산 • ----------------------------------------- • voidGraph::DfnLow(constintx) { // 정점 x에서 DFS를 시작 • num = 1; // num는 classGraph의 int데이타 멤버 • dfn= new int[n]; // dfn은 classGraph에 int*로 선언 • low = new int[n]; // low는 classGraph에 int*로 선언 • for(inti=0; i<n; i++) dfn[i] = low[i] = 0; • DfnLow(x,-1); // 정점 x에서 시작 • delete[] dfn; • delete[] low; • } • voidGraph::DfnLow(constintu, constintv) { • // 정점 u에서 출발하여 깊이우선 탐색을 수행하면서 dfn과 • // low를 계산. • // v는 생성된 신장 트리에서 u의 부모 (존재하는 경우) • dfn[u] = low[u] = num++; • for(u로부터 인접한 각 정점 w에 대해) • // 실제 코드는 그래프 표현 방법에 좌우됨 • if(dfn[w]==0) { // w가 아직 방문하지 않은 정점이면 • DfnLow(w,u); • low[u] = min2(low[u],low[w]); • } • else if(w!=v) low[u] = min2(low[u],dfn[w]); // 백 간선 • } • ----------------------------------------- • 프로그램 6.4: dfn과 low의 계산

  31. 6.3 최소비용 신장트리

  32. 6.3 최소비용 신장트리 • - 최소비용 신장트리(minimum cost spanning tree) • : 최저의 비용을 갖는 신장트리 • - Kruskal, Prim, Sollin알고리즘 • - 갈망법(greedy method) • ⑴ 최적의 해를 단계별로 구한다 • ⑵ 각 단계에서는 몇개의 판단 기준에 따라 최상의 결정을 내린다 • ⑶ 한번 내려진 결정은 뒤에 번복이 불가능하므로 각각의 결정이 가능한 해를 도출해낼 수 있는 지 확인 • - 신장트리의 제한 조건 • (1) 그래프내에 있는 간선들만을 사용 • (2) 정확하게 n-1개의 간선만을 사용 • (3) 사이클을 생성하는 간선을 사용 금지

  33. 6.3 최소비용 신장트리 • ▶ Kruskal알고리즘 • - 알고리즘 • •한번에 하나씩 T에 간선을 추가해가면서 최소비용 신장트리 T를 구축 • •T에 포함될 간선을 비용의 크기순으로 선택 • •이미 T에 포함된 간선들과 사이클을 형성하지 않는 간선만을 T에 추가

  34. 6.3 최소비용 신장트리 • -예제 6.4 • 그림 6.22: Kruskal알고리즘의 각 단계

  35. 6.3 최소비용 신장트리 • ----------------------------------------- • 1 T = Ø • 2 while((T가 n-1개 미만의 간선을 포함) && (E가 공백이 아님)) { • 3 E에서 최소 비용 간선 (v,w) 선택; • 4 E에서 (v,w)를 삭제; • 5 if((v,w)가 T에서 사이클을 형성하지 않음) • T에 (v,w)를 추가; • 6 else(v,w)를 거부; • 7 } • 8 if(T가 n-1개 미만의 간선을 포함) • cout<< "신장 트리 없음" << endl; • ----------------------------------------- • 프로그램 6.6: Kruskal알고리즘 • - 정리 6.1 • •G를 무방향 연결 그래프라 하자. Kruskal알고리즘은 • 최소비용 신장트리를 생성한다.

  36. 6.3 최소비용 신장트리 • ▶ Prim 알고리즘 • - 알고리즘 • •한번에 한 간선씩 최소비용 신장트리를 구축 • •각 단계에서 선택된 간선의 집합은 트리 • •하나의 정점으로 된 트리 T에서 시작 • •최소 비용 간선 (u,v)를 구해 T ∪ {(u,v)}이 트리가 되면 T에 추가 • •T에 n-1개의 간선이 포함될 때까지 간선의 추가 단계를 반복 • •추가된 간선이 사이클을 형성하지 않도록 각 단계에서 간선 (u,v)를 선택할 때 u 또는 v중 오직 하나만 T에 속한 것을 고른다. • ----------------------------------------- • // G가 최소한 하나의 정점을 가진다고 가정. • TV = {0}; // 정점 0으로 시작. 간선은 비어있음. • for(T= Ø ; T의 간선수가 n-1보다 적음; (u,v)를 T에 추가) { • u ∈ TV이고 v  TV인 최소 비용 간선을 (u,v)라 함; • if(그런 간선이 없음) break; • v를 TV에 추가; • } • if(T의 간선수가 n-1보다 적음) • cout<< "신장트리 없음" << endl; • ----------------------------------------- • 프로그램 6.7: Prim 알고리즘

  37. 6.3 최소비용 신장트리 • 그림 6.23: Prim 알고리즘의 단계들

  38. 6.3 최소비용 신장트리 • ▶ Sollin알고리즘 • - 알고리즘 • •각 단계에서 여러개의 간선을 선택 • •각 단계에서는 포리스트에 있는 각 트리에 대해 하나의 간선을 선택 • •이 간선은 오직 하나의 정점만 그 트리에 속한 최소 비용 간선 • •선택된 간선은 구축중인 신장트리에 추가 • •오직 하나의 트리만이 존재 or 더 이상 선택할 간선이 없을 때 종료 • 그림 6.24: Sollin알고리즘의 단계들

  39. 6.4 최단경로와 이행적 폐쇄

  40. 6.4 최단경로와 이행적 폐쇄 • ▶ 단일 시발점/모든 종점: 양수 간선 비용 • - 문제 : 시발 정점 v에서부터 G의 모든 다른 정점까지의 최단경로를 구하는 것 • 그림 6.25: 그래프와 정점 0에서 모든 종점까지의 최단경로

  41. 6.4 최단경로와 이행적 폐쇄 • - 알 수 있는 사실들 • •정점 v를 포함하여 이미 최단 경로가 발견된 정점의 집합을 S • •S에 속하지 않은 w에 대해서 dist[w]를 v에서 시작하여 S에 있는 정점만을 거쳐 w까지의 최단경로의 길이 • (1) 만일 다음으로 짧은 최단경로가 정점 u까지의 경로라면 v에서 u로의 경로는 오직 S에 속한 정점들만을 통하게 된다. • (2) 다음에 생성되는 경로의 종점은 S에 없는 정점들중에서 최소의 거리 dist[u]를 가진 정점 u가 되어야 한다. • (3) 일단 (2)에서 선택된 정점 u는 S의 원소가 된다. v에서 u로의 최단 경로는 (2)의 선택 과정을 통해 얻어진다. 이때, v에서 시작하여 S에 있는 정점만을 통해 현재 S에 속하지 않은 w까지의 최단경로의 길이는 감소될 수 있다. • - ShortestPath알고리즘

  42. 6.4 최단경로와 이행적 폐쇄 • - 클래스 정의 • class Graph • { • private: • int length[nmax][nmax]; • int dist[nmax]; • Boolean s[nmax]; • public: • void ShortestPath(constint, constint); • int choose(constint); • };

  43. 6.4 최단경로와 이행적 폐쇄 • ----------------------------------------- • 1 voidGraph::ShortestPath(constintn, constintv) • 2 // dist[j],0≤j<n는 n개의 정점을 가진 방향 그래프 G에서 • //정점 v로부터 정점 j까지 • 3 // 의 최단 경로 길이로 설정됨. 간선의 길이는 length[j][j] • //로 주어짐. • 4 { • 5 for(inti=0; i<n; i++) • { s[i] = FALSE; dist[i] = length[v][i]; } // 초기화 • 6 s[v] = TRUE; • 7 dist[v] = 0; • 8 for(i=0; i<n-2; i++) { // 정점 v로부터 n-1개 경로를 결정 • 9 intu = choose(n); • // choose는 dist[u] = minimum dist[w]인 u를 반환 • 10 // (여기서 s[w]=FALSE) • 11 s[u] = TRUE; • 12 for(intw=0; w<n; w++) • 13 if(!s[w]) • 14 if(dist[u] + length[u][w] < dist[w]) • 15 dist[w] = dist[u] + length[u][w]; • 16 } // for(i=0; ...)의 끝 • 17 } • ----------------------------------------- • 프로그램 6.8: 최단경로의 결정

  44. 6.4 최단경로와 이행적 폐쇄 • - ShortestPath의 분석: • n개의 정점을 가진 그래프에 대한 수행시간은 O(n2) • - 예제 6.5 • 그림 6.26: 예제 6.5에 대한 방향그래프

  45. 6.4 최단경로와 이행적 폐쇄 • 그림 6.27: 그림 6.26의 방향그래프에 대한 ShortestPath의 작동

  46. 6.4 최단경로와 이행적 폐쇄 • ▶ 단일 시발점/모든 종점: 일반적인 가중치 • - 음수 길이 사이클이 존재할 경우 최단 길이 경로가 존재하지 않는다. • 그림 6.28: 음의 길이 간선을 가진 방향 그래프 • 그림 6.29: 음의 길이 사이클을 가진 방향 그래프 • - 동적 프로그래밍 방법 • : 모든 u에 대해 distn-1[u]를 구함 • distk[u] = min{distk-1[u], min{distk-1[i] + length[i][u]}}

  47. 6.4 최단경로와 이행적 폐쇄 • - 예제 6.6 • 그림 6.30: 음의 길이 간선을 갖는 최단 경로

  48. 6.4 최단경로와 이행적 폐쇄 • - Bellman과 Ford 알고리즘 • ----------------------------------------- • 1 voidGraph::BellmanFord(constintn, constintv) • 2 // 음의 길이 간선을 가지는 단일 시발점 모든 종점 • //최단 경로 • 3 { • 4 for(inti=0; i<n; i++) dist[i] = length[v][i]; // dist 초기화 • 5 for(intk=2; k<=n-1; k++) • 6 for(u!=v이고 최소한 하나의 진입 간선을 갖는 u에 • 대해) • 7 for(그래프의 각 <i,u>에 대해) • 8 if(dist[u]>dist[i]+length[i][u]) dist[u] = dist[i] + length[i][u]; • 9 } • ----------------------------------------- • 프로그램 6.9: 최단 경로를 계산하는 Bellman과 Ford 알고리즘 • - BellmanFord의 분석 • •인접 행렬 O(n3), 인접 리스트 O(ne)

  49. 6.4 최단경로와 이행적 폐쇄 • ▶ 모든 쌍의 최단경로 • - u≠v인 모든 정점의 쌍 u와 v간의 최단경로를 구하는 것 • Ak[i][j] = min{Ak-1[i][j], Ak-1[i][k] + Ak-1[k][j]}, k≥0 • A-1[i][j] = length[i][j] • ----------------------------------------- • 1 voidGraph::AllLengths(constintn) • 2 // length[n][n]은 n개의 정점을 가진 그래프의 인접 행렬 • 3 // a[i][j]는 i와 j 사이의 최단 경로의 길이 • 4 { • 5 for(inti=0; i<n; i++) • 6 for(intj=0; j<n; j++) • 7 a[i][j] = length[i][j]; // length를 a에 복사 • 8 for(intk=0; k<n; k++) // 제일 큰 정점의 인덱스가 k인 경 //로에 대해 • 9 for(i=0; i<n; i++) // 가능한 모든 정점의 쌍에 대해 • 10 for(intj=0; j<n; j++) • 11 if((a[i][k]+a[k][j])<a[i][j]) a[i][j] = a[i][k] + a[k][j]; • 12 } • ----------------------------------------- • 프로그램 6.10: 모든 쌍의 최단경로 • - AllLengths의 분석 • •전체 시간은 O(n3)

  50. 6.4 최단경로와 이행적 폐쇄 • - 예제 6.7 • 그림 6.31: 모든 쌍의 최단 경로 문제의 예

More Related