slide1 n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
자료구조 PowerPoint Presentation
Download Presentation
자료구조

Loading in 2 Seconds...

play fullscreen
1 / 69

자료구조 - PowerPoint PPT Presentation


  • 317 Views
  • Uploaded on

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

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
slide1

자료구조

제 6 장 그래프

slide3
6.1 그래프 추상 데이타 타입
  • ▶ 개요
  • - Koenigsberg 다리 문제
  • - 차수(degree) : 정점에 연결된 간선의 수
  • - 오일러 행로(Eulerian walk)
  • 그림 6.1: (a) Koenigsberg의 Pregal강의 일부
  • (b) Euler의 그래프
slide4
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: 세개의 예제 그래프
slide5
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'
slide6
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: 부분그래프
slide7
6.1 그래프 추상 데이타 타입
  • - 연결요소(connected component)
  • :최대연결부분그래프(maximalconnected subgraph)
  • - 강력 연결(strongly connected)
  • : 방향그래프에서 V(G)에 속한 서로 다른 두 정점 u, v
  • 의 모든 쌍에 대해서, u에서 v로, 또한 v에서 u로의
  • 방향 경로(directed path)가 존재
  • - 강력 연결요소(strongly connected component)
  • : 강하게 연결된 최대 부분그래프
  • 그림 6.5: 두 개의 연결요소를 갖는 그래프
slide8
6.1 그래프 추상 데이타 타입
  • 그림 6.6: G3의 강력 연결요소
  • - 차수(degree) : 정점에 부속한 간선들의 수
  • - 진입차수(in-degree)
    • : 임의의 정점 v가 머리가 되는 간선들의 수
  • - 진출차수(out-degree)
    • : v가 꼬리가 되는 간선들의 수
  • - 간선의 수
  • (n개의 정점, e개의 간선, 정점 i의 차수를 di)
  • - 다이그래프(digraph) : 방향 그래프
slide9
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: 그래프 추상 데이타 타입
slide10
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)
slide11
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)
  • : 리스트가 표현하는 정점에 인접한 각 정점에 대해
  • 하나의 노드를 둠
slide12
6.1 그래프 추상 데이타 타입
  • 그림 6.8: 인접리스트
slide13
6.1 그래프 추상 데이타 타입
  • 그림 6.9: 그래프 G4의 순차적인 표현
  • 그림 6.10: G3(그림 6.2(c))의 역인접리스트
slide14
6.1 그래프 추상 데이타 타입
  • 그림 6.11: 그림 6.2(c)의 그래프 G3의 직교 리스트 표현
slide15
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;
  • }
slide16
6.1 그래프 추상 데이타 타입
  • 그림 6.12: 그림 6.2(a)의 G1에 대한 인접다중리스트
  • - 가중치 간선 (Weighted Edges)
  • • 그래프의 간선에 가중치(weights) 부여
  • • 인접행렬 : 항 A[i][j]에 가중치 정보 저장
  • • 인접리스트 : 노드 구조에 weight 필드를 추가
  • • 네트워크(network) : 가중치 간선을 가진 그래프
slide18
6.2 기본적인 그래프 연산
  • ▶ 깊이 우선 탐색
  • - 깊이 우선 탐색(DFS; Depth First Search)
  • ⑴ 출발 정점 v를 방문
  • ⑵ v에 인접하고 방문하지 않은 한 정점 w를 선택
  • ⑶ w를 시작점으로 다시 깊이 우선 탐색 시작
  • ⑷ 모든 인접 정점을 방문한 정점 u에 도달하면, 최근에 방문한 정점 중 아직 방문을 안한 정점 w와 인접하고 있는 정점으로 되돌아감
  • ⑸ 정점 w로부터 다시 깊이 우선 탐색 시작
  • ⑹ 방문이 된 정점들로부터 방문이 안된 정점으로 더 이상 갈 수 없을 때 종료
slide19
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: 깊이 우선 탐색
slide20
6.2 기본적인 그래프 연산
  • - 예제 6.1
  • •0, 1, 3, 7, 4, 5, 2, 6 순으로 방문
  • 그림 6.16: 그래프 G와 그 인접리스트
  • - DFS의 분석
  • •탐색을 끝내는 시간 O(e)
  • •v에 인접한 모든 정점들을 찾는데 O(n)의 시간
  • •총 시간은 O(n2)
slide21
6.2 기본적인 그래프 연산
  • ▶ 너비 우선 탐색
  • - 너비 우선 탐색(BFS; Breath First Search)
  • ⑴ 시작 정점 v를 방문
  • ⑵ v에 인접한 모든 정점들을 방문
  • ⑶ 새롭게 방문한 정점들에 인접하면서 아직 방문하지 못한 정점들을 방문
  • - 예제 6.2
  • • 0, 1, 2, 3, 4, 5, 6, 7 순으로 방문
slide22
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: 너비 우선 탐색
slide23
6.2 기본적인 그래프 연산
  • - BFS의 분석
  • •전체 시간 O(n2)
  • •인접 리스트 표현 : 전체 비용 O(e)
slide24
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)
slide25
6.2 기본적인 그래프 연산
  • ▶ 신장트리
  • - 신장트리(spanning tree) : G의 간선들로만 구성되고 G의 모든 정점들이 포함된 트리
  • •깊이우선 신장트리(depth first spanning tree)
  • •너비우선 신장트리(breath first spanning tree)
  • 그림 6.17: 완전 그래프와 이 그래프의 세 신장트리
  • 그림 6.18: 그림 6.16의 그래프에 대한 깊이우선 및
  • 너비우선 신장트리
slide26
6.2 기본적인 그래프 연산
  • - 예제 6.3 [회로 등식의 생성]
  • ⑴ 전기 네트워크에 대한 신장트리 구함
  • ⑵ 비트리 간선을 신장트리에 한번에 하나씩 도입
  • ⑶ Kirchoff의 제 2 법칙 이용하여 회로 등식 얻음
  • -신장트리는G의최소부분그래프(minimal subgraph) G'로서 V(G') = V(G)이고 G'는 연결되어 있음
  • - 신장트리는 n-1개의 간선 가짐
slide27
6.2 기본적인 그래프 연산
  • ▶ 이중결합요소
  • - 단절점(articulation point)
  • : 그래프 G의 정점들중 이 정점과 이 정점에 부속한 모든 간선들 삭제시, 최소한 두개의 연결요소를 갖는 그래프 G'가 되게 하는 정점 v
  • 그림 6.19: 연결 그래프와 이중결합요소들
  • - 이중결합그래프(biconnected graph)
  • : 단절점이 없는 연결 그래프
  • - 이중결합요소(biconnected component)
  • : 최대이중결합부분그래프(maximal biconnected subgraph) H
slide28
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)는 백 간선
slide29
6.2 기본적인 그래프 연산
  • 그림 6.21: 그림 6.20(b)의 신장 트리에 대한 dfn값과 low값
slide30
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의 계산
slide32
6.3 최소비용 신장트리
  • - 최소비용 신장트리(minimum cost spanning tree)
  • : 최저의 비용을 갖는 신장트리
  • - Kruskal, Prim, Sollin알고리즘
  • - 갈망법(greedy method)
  • ⑴ 최적의 해를 단계별로 구한다
  • ⑵ 각 단계에서는 몇개의 판단 기준에 따라 최상의 결정을 내린다
  • ⑶ 한번 내려진 결정은 뒤에 번복이 불가능하므로 각각의 결정이 가능한 해를 도출해낼 수 있는 지 확인
  • - 신장트리의 제한 조건
  • (1) 그래프내에 있는 간선들만을 사용
  • (2) 정확하게 n-1개의 간선만을 사용
  • (3) 사이클을 생성하는 간선을 사용 금지
slide33
6.3 최소비용 신장트리
  • ▶ Kruskal알고리즘
  • - 알고리즘
  • •한번에 하나씩 T에 간선을 추가해가면서 최소비용 신장트리 T를 구축
  • •T에 포함될 간선을 비용의 크기순으로 선택
  • •이미 T에 포함된 간선들과 사이클을 형성하지 않는 간선만을 T에 추가
slide34
6.3 최소비용 신장트리
  • -예제 6.4
  • 그림 6.22: Kruskal알고리즘의 각 단계
slide35
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알고리즘은
  • 최소비용 신장트리를 생성한다.
slide36
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 알고리즘
slide37
6.3 최소비용 신장트리
  • 그림 6.23: Prim 알고리즘의 단계들
slide38
6.3 최소비용 신장트리
  • ▶ Sollin알고리즘
  • - 알고리즘
  • •각 단계에서 여러개의 간선을 선택
  • •각 단계에서는 포리스트에 있는 각 트리에 대해 하나의 간선을 선택
  • •이 간선은 오직 하나의 정점만 그 트리에 속한 최소 비용 간선
  • •선택된 간선은 구축중인 신장트리에 추가
  • •오직 하나의 트리만이 존재 or 더 이상 선택할 간선이 없을 때 종료
  • 그림 6.24: Sollin알고리즘의 단계들
slide40
6.4 최단경로와 이행적 폐쇄
  • ▶ 단일 시발점/모든 종점: 양수 간선 비용
  • - 문제 : 시발 정점 v에서부터 G의 모든 다른 정점까지의 최단경로를 구하는 것
  • 그림 6.25: 그래프와 정점 0에서 모든 종점까지의 최단경로
slide41
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알고리즘
slide42
6.4 최단경로와 이행적 폐쇄
  • - 클래스 정의
  • class Graph
  • {
  • private:
  • int length[nmax][nmax];
  • int dist[nmax];
  • Boolean s[nmax];
  • public:
  • void ShortestPath(constint, constint);
  • int choose(constint);
  • };
slide43
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: 최단경로의 결정
slide44
6.4 최단경로와 이행적 폐쇄
  • - ShortestPath의 분석:
  • n개의 정점을 가진 그래프에 대한 수행시간은 O(n2)
  • - 예제 6.5
  • 그림 6.26: 예제 6.5에 대한 방향그래프
slide45
6.4 최단경로와 이행적 폐쇄
  • 그림 6.27: 그림 6.26의 방향그래프에 대한 ShortestPath의 작동
slide46
6.4 최단경로와 이행적 폐쇄
  • ▶ 단일 시발점/모든 종점: 일반적인 가중치
  • - 음수 길이 사이클이 존재할 경우 최단 길이 경로가 존재하지 않는다.
  • 그림 6.28: 음의 길이 간선을 가진 방향 그래프
  • 그림 6.29: 음의 길이 사이클을 가진 방향 그래프
  • - 동적 프로그래밍 방법
  • : 모든 u에 대해 distn-1[u]를 구함
  • distk[u] = min{distk-1[u], min{distk-1[i] + length[i][u]}}
slide47
6.4 최단경로와 이행적 폐쇄
  • - 예제 6.6
  • 그림 6.30: 음의 길이 간선을 갖는 최단 경로
slide48
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)
slide49
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)
slide50
6.4 최단경로와 이행적 폐쇄
  • - 예제 6.7
  • 그림 6.31: 모든 쌍의 최단 경로 문제의 예
slide51
6.4 최단경로와 이행적 폐쇄
  • ▶ 이행적 폐쇄
  • - 이행적 폐쇄 행렬(A+)
  • i에서 j로의 경로 길이 >0 ⇒ A+[i][j] = 1 인 행렬
  • - 반사 이행적 폐쇄 행렬(A*)
  • i에서 j로의 경로 길이 0 ⇒ A+[i][j] = 1 인 행렬
  • 그림 6.32: 그래프 G와 인접행렬 A,A+,A*
slide52
6.4 최단경로와 이행적 폐쇄
  • - A+
  • •간선 <i, j>  G ⇒ length[i][j] = 1,
  • otherwise, length[i][j] = +∞
  • •AllLengths종료시 length[i][j] < +∞
  • ⇒ A+[i][j]=1
  • - A* : A+의 대각선에 있는 항을 모두 1로
slide54
6.5 작업 네트워크
  • ▶ AOV네트워크
  • - AOV(activity on vertex) 네트워크 : 정점이 작업, 간선이 작업간의 선행 관계를 나타내는 방향그래프 G
  • -----------------------------------------과목번호 과목명 선수과목
  • --------------------------------------
  • C1 프로그래밍 I 없음
  • C2 이산 수학 없음
  • C3 자료 구조 C1, C2
  • C4 수학 I 없음
  • C5 수학 IIC4
  • C6 선형 대수 C5
  • C7 알고리즘 분석 C3, C6
  • C8 어셈블리어 C3
  • C9 운영 체제 C7, C8
  • C10 프로그래밍 언어론 C7
  • C11 컴파일러 설계 C10
  • C12 인공 지능 C7
  • C13 계산 이론 C7
  • C14 병렬 알고리즘 C13
  • C15 수치 해석 C5
  • (a) 가상적인 대학에서 컴퓨터 과학 학위에 필요한 과목들
slide55
6.5 작업 네트워크
  • (b) 과목은 정점으로, 선수과목은 간선으로 표현한 AOV 네트워크
slide56
6.5 작업 네트워크
  • - 정의
  • •정점 i로부터 정점 j로의 방향 경로 존재하면 정점 i를 정점 j의 선행자(predecessor)
  • •간선 <i, j>가 존재하면 정점 i를 정점 j의 직속 선행자(immediate predecessor)
  • •i가 j의 선행자 ⇒ j는 i의 후속자(successor)
  • •i가 j의 직속 선행자 ⇒ j는 i의 직속 후속자(immediate successor)
  • - 정의
  • •모든 세 쌍 i, j, k에 대해 i·j 이고 j·k ⇒ i·k 가 성립하면 관계 ·는 이행적(transitive)
  • •S에 속한 모든 원소 x에 대해 x·x가 성립하지 않으면 관계·는 집합 S상에서 비반사적 (irreflexive)
  • •부분 순서(partial order)
  • : 이행적, 비반사적인 선행 관계
  • - 위상순서(topological order)
  • : 임의의 두 정점 i, j에 대해 네트워크에서 i가 j의 선행자이면 선형순서에서도 i가 j 앞에 있는 그래프 정점의 형 순서
slide57
6.5 작업 네트워크
  • -----------------------------------------
  • 1 AOV네크워크를 입력. n을 정점의 수라 함.
  • 2 for(inti = 0; i < n; i++) // 정점들을 출력
  • 3 {
  • 4 if(모든 정점이 선행자가 있음) return;
  • // 네크워크에 사이클이 있어 수행 불가능.
  • 5 // 선행자가 없는 정점 v를 선택;
  • 6 cout<< v;
  • 7 // 정점 v와 v에서 나온 모든 간선들을 네트워크에 //서 삭제;
  • 8 }
  • -----------------------------------------
  • 프로그램 6.11: 위상 정렬 알고리즘의 설계
slide58
6.5 작업 네트워크
  • - 예제 6.8
  • 그림 6.36: AOV네트워크에 대한 프로그램 6.11의 작동. (진한 정점들은 삭제 후보를 표현)
slide59
6.5 작업 네트워크
  • - 클래스 정의
  • class Graph {
  • private:
  • List<int> *HeadNodes;
  • int *count;
  • int n;
  • public:
  • Graph(constint vertices = 0):n(vertices) {
  • HeadNodes= new List<int>[n];
  • count = new int[n];
  • };
  • void TopologicalOrder();
  • };
slide60
6.5 작업 네트워크
  • 그림 6.37: 위상 정렬 알고리즘에 의해 사용되는 내부 표현
slide61
6.5 작업 네트워크
  • - TopologicalOrder의 분석
  • •점근적 계산 시간 O(e+n)
  • -----------------------------------------
  • 1 voidGraph::TopologicalOrder() {
  • 2 // 네트워크의 n개 정점이 위상 순서로 나열됨
  • 4 inttop = -1;
  • 5 for(inti=0; i<n; i++) // 선행자가 없는 정점들의 연결 스택을 생성
  • 6 if(count[i]==0) count[i] = top; top = i;
  • 7 for(i=0; i<n; i++)
  • 8 if(top==-1) cout<< "네트워크에 사이클이 존재" << endl; return;
  • 9 else {
  • 10 intj = top; top = count[top]; // 정점 하나를 스택에서 꺼냄
  • 11 cout<< j << endl;
  • 12 ListIterator<int> li(HeadNodes[j]);
  • 13 if(!Li.NotNull()) continue;
  • 14 intk = *li.First();
  • 15 while(1) { // j의 후속자 정점의 계수를 감소시킴
  • 16 count[k]--;
  • 17 if(count[k]==0) {count[k] = top; top = k;} // 정점 k를 스택에 첨가
  • 18 if(li.NextNotNull()) k = *li.Next(); // k는 j의 후속자
  • 19 else break;
  • 20 }
  • 21 } // else의 끝
  • 22}
  • -----------------------------------------
  • 프로그램 6.12: 위상 정렬
slide62
6.5 작업 네트워크
  • ▶ AOE네트워크
  • - AOE(activity on edge) 네트워크
  • •방향 간선 : 프로젝트에서 수행되어야 할 작업
  • •정점 : 사건(event)
  • (사건은 어떤 작업의 완료를 알림)
  • •정점에서 나오는 간선이 의미하는 작업은 그 정점에서의 사건이 발생할 때까지 시작될 수 없다.
slide63
6.5 작업 네트워크
  • (a) 가상프로젝트의 작업 네트워크
  • (b) 네트위크 (a)의 몇몇 사건의 의미
  • 그림 6.38: AOE네트워크
slide64
6.5 작업 네트워크
  • - 임계경로(critical path)
  • : 시작 정점에서 종료 정점까지의 최장 경로(longest path)
  • - 가장 이른 시간(earliest time) e(i)
  • : 시작 정점 0에서 정점 i 까지의 최장 경로 길이
  • - 가장 늦은 시간(latest time) l(i)
  • : 프로젝트 기간을 지연시키지 않으면서 가장 늦게 작업을 시작할 수 있는 시간
  • - 임계작업(critical activity) : e(i) = l(i) 인 작업
  • - 임계경로 분석의 목적
  • : 임계작업들을 식별해내어 가용 자원을 집중시킴으로써 프로젝트 완료 시간을 단축
slide65
6.5 작업 네트워크
  • - 가장 이른 작업 시간과 가장 늦은 작업 시간
  • •e(i)= ee[k]
  • (ee[k] : 가장 이른 사건 발생 시간)
  • •l(i) = le[l] - 작업 ai의 기간
  • (le[l] : 가장 늦은 사건 발생 시간)
  • - 가장 이른 시간의 계산
  • ee[j] =
  • (P(j)는 j의 직속 선행자의 집합)
slide66
6.5 작업 네트워크
  • (a) 그림 6.38(a)에 대한 인접리스트
  • (b) ee 의 계산
  • 그림 6.39: 수정된 TopologicalOrder(프로그램 6.12)를 이용한 ee값의 계산
slide67
6.5 작업 네트워크
  • -----------------------------------------
          • le[8]=ee[8]=18
          • le[6]=min{le[8]-2}=16
          • le[7]=min{le[8]-4}=14
          • le[4]=min{le[6]-9, le[7]-7}=7
          • le[1]=min{le[4]-1}=6
          • le[2]=min{le[4]-1}=6
          • le[5]=min{le[7]-4}=10
          • le[3]=min{le[5]-2}=8
          • le[0]=min{le[1]-6, le[2]-4, le[3]-5}=0
  • (c) 위상순서의 역순으로 le를 계산
  • -----------------------------------------
  • 그림 6.40: 그림 6.38(a)의 AOE네크워크에 대한 le의 계산
slide68
6.5 작업 네트워크
  • 그림 6.41: e, l, 임계성 값
slide69
6.5 작업 네트워크
  • 그림 6.42: 모든 비임계 작업을 삭제한 후의 그래프
  • 그림 6.43: 도달 불가능한 작업을 가진 AOE네트워크