270 likes | 480 Views
제 6 장 그래프. 6.4 최단경로와 이행적 폐쇄. 6.4 최단경로와 이행적 폐쇄. A 로부터 B 로 가는 길이 있는가 ? A 로부터 B 로 가는길이 있다면 어느길이 짧은가 ? 최단경로 (shortest path) 단일 출발점 모든 도착지 (single source all destinations) v0(source) 에서 다른 모든 정점 ( 도착지 ) 까지의 최단경로 경로 길이의 증가순 ( 방향그래프에서 ). 6.4 최단경로와 이행적 폐쇄. 6.4 최단경로와 이행적 폐쇄. 가중치 (weight)
E N D
6.4 최단경로와 이행적 폐쇄 • A로부터 B로 가는 길이 있는가? • A로부터 B로 가는길이 있다면 어느길이 짧은가? • 최단경로(shortest path) • 단일 출발점 모든 도착지(single source all destinations) • v0(source)에서 다른 모든 정점(도착지)까지의 최단경로 • 경로 길이의 증가순(방향그래프에서)
6.4 최단경로와 이행적 폐쇄 • 가중치(weight) • 양의 값 : adjacent • : not adjacent • found[i] : if found[i]=TRUE->vi까지의 최단경로 발견 • distance[i] : v0에서 S내의 정점만을 거친 vi까지의 최단거리(S=최단경로가 발견된 정점의 집합) • 초기치 : distance[i]=cost[0][i] • cost[i][j] : <i,j>의 가중치
6.4 최단경로와 이행적 폐쇄 • 그래프 : 비용인접행렬(cost adjacency matrix)로 표현 • 최단경로 i-k=(vi,…,vj,vk) shortest + shortest => shortest
6.4 최단경로와 이행적 폐쇄 • Repeat • 다음 조건을 만족하는 i를 찾음 found[i]=FALSE && distance[i] =min{distance[j]}, all j, found[j]=FALSE • found[i]<-TRUE (S<-SU{vi}) • 모든 j (found[j]=FALSE)에 대해서 distance[j]<-min{distance[j],distance[i]+cost[i][j]} (S에 포함되지 않은 모든 distance를 조정)
6.4 최단경로와 이행적 폐쇄 cost 비용인접행렬 0 1 2 3 4 5 0 50 10 45 1 15 10 2 20 15 3 20 35 4 30 5 3
6.4 최단경로와 이행적 폐쇄 1. S={v0} : 초기는 공백 vertex 0 1 2 3 4 5 distance 0 50 10 999 45 999 S 1 0 0 0 0 0
6.4 최단경로와 이행적 폐쇄 min vertex 0 1 2 3 4 5 distance 0 50 10 999 45 999 S 1 0 0 0 0 0
6.4 최단경로와 이행적 폐쇄 2. S=SU{v2} = {v0,v2} min vertex 0 1 2 3 4 5 distance 0 50 10 999 45 999 S 1 0 1 0 0 0
vertex 0 1 2 3 4 5 distance 0 50 10 999 45 999 • 2. S=SU{v2} = {v0,v2} • distance(1)<-min{distance(1),distance(2)+(v2,v1,999)} 50 • distance(3)<-min{distance(2),distance(2)+(v2,v3,15)} 25 • distance(4)<-min{distance(4),distance(2)+(v2,v4,999)} 45 • distance(5)<-min{distance(5),distance(2)+(v2,v5,999)} 999 S 1 0 1 0 0 0 vertex 0 1 2 3 4 5 distance 0 50 10 25 45 999 S 1 0 1 0 0 0
vertex 0 1 2 3 4 5 distance 0 50 10 25 45 999 S 1 0 1 0 0 0 3. S=SU{v3}={v0,v2,v3} • distance(1)<-min{distance(1),distance(3)+(v3,v1,20)} 45 • distance(4)<-min{distance(4),distance(3)+(v3,v4,35)} 45 • distance(5)<-min{distance(5),distance(3)+(v3,v5,999)} 999 vertex 0 1 2 3 4 5 distance 0 45 10 25 45 999 S 1 0 1 1 0 0
vertex 0 1 2 3 4 5 distance 0 45 10 25 45 999 S 1 0 1 1 0 0 4. S=SU{v1}={v0,v1,v2,v3} • Distance(4)<-min{distance(4),distance(1)+(v1,v4,10)} 45 • Distance(5)<-min{distance(5),distance(3)+(v3,v5,999)} 999 vertex 0 1 2 3 4 5 distance 0 45 10 25 45 999 S 1 1 1 1 0 0
vertex 0 1 2 3 4 5 distance 0 45 10 25 45 999 S 1 1 1 1 0 0 5. S=SU{v4}={v0,v1,v2,v3,v4} • Distance(5)<-min{distance(5),distance(4)+(v3,v5,999)}999 vertex 0 1 2 3 4 5 distance 0 45 10 25 45 999 S 1 1 1 1 1 0
vertex 0 1 2 3 4 5 distance 0 45 10 25 45 999 S 1 1 1 1 1 0 6. S=SU{v5}={v0,v1,v2,v3,v4,v5} vertex 0 1 2 3 4 5 distance 0 45 10 25 45 999 S 1 1 1 1 1 1
void shortestpath(int v, int cost[][MAX_VERTICES], int distance[], int n, short int found[]) { /* distance[i]는 정점 v에서 i로의 최단 경로 표현, 정점 i로부터 최단 경로가 발견되었으면 found[i]는 1이고 그렇지 않으면 0, cost는 인접행렬*/ int i, u, w; for(i=0;i<n;i++){ found[i]=FALSE; distance[i]=cost[v][i]; } found[v]=TRUE; distance[v]=0; for(i=0;i<n-2;i++){ u=choose(distance,n,found); found[u]=TRUE; for(w=0;w<n;w++) if(!found[w]) if(distance[u]+cost[u][w]<distance[w]) distance[w]=distance[u]+cost[u][w]; } }
int choose(int distance[], int n, short int found[]) { /* 아직 조사 안된 정점 중에서 distance의 값이 최소인 것을 찾음 */ int i, min, minpos; min=INT_MAX; minpos=-1; for(i=0;i<n;i++) if(distance[i]<min&&!found[i]){ min=distance[i]; minpos=i; } return minpos; }
6.4 최단경로와 이행적 폐쇄 • 모든쌍의 최단경로 • 음수의 가중치를 가지는 사이클은 없음 • 비용인접행렬 cost[i][i]=0 cost[i][j]=weight if <i,j>E(G) cost[I][j]= otherwise A-1[i][j]=cost[i][j] Ak[i][j]=k보다 더 큰 중간정점을 지나지 않는 i->j최단경로 An-1[i][j]=i->j 최단경로 A-1, A0, A1,… An-1
6.4 최단경로와 이행적 폐쇄 • for k>=1, Ak[i][j]=min(Ak-1[i][j], Ak-1[i][k]= Ak-1[k][j]) A-1[i][j]= cost[i][j]
6.4 최단경로와 이행적 폐쇄 A-1 0 1 2 0 0 4 11 1 6 0 2 2 3 0
6.4 최단경로와 이행적 폐쇄 A-1 0 1 2 0 0 4 11 1 6 0 2 2 3 0 k=0 A0(0,1)=min{A-1(0,1), A-1(0,0)+A-1(0,1)} A0(0,2)=min{A-1(0,2), A-1(0,0)+A-1(0,2)} A0(1,0)=min{A-1(1,0), A-1(1,0)+A-1(0,0)} A0(1,2)=min{A-1(1,2), A-1(1,0)+A-1(0,2)} A0(2,0)=min{A-1(2,0), A-1(2,0)+A-1(0,0)} A0(2,1)=min{A-1(2,1), A-1(2,0)+A-1(0,1)} A0 0 1 2 0 0 4 11 1 6 0 2 2 3 7 0
6.4 최단경로와 이행적 폐쇄 A0 0 1 2 0 0 4 11 1 6 0 2 2 3 7 0 A1 0 1 2 A2 0 1 2 0 0 4 6 0 0 4 6 1 6 0 2 1 5 0 2 2 3 7 0 2 3 7 0
void allcosts(int cost[][MAX_VERTICES], int distance[][MAX_VERTICES], int n) { /* 각 정점에서 다른 모든 정점으로의 거리 계산, cost는 인접 행렬, distance는 거리값의 행렬 */ int i,j,k; for (i=0;i<n;i++) for (j=0;j<n;j++) distance[i][j]=cost[i][j]; for (k=0;k<n;k++) for (i=0;i<n;i++) for (j=0;j<n;j++) if distance[i][k]+distance[k][j]<distance[i][j]) distnace[i][j]=distance[i][k]+distance[k][j]; }
6.4 최단경로와 이행적 폐쇄 • 이행적폐쇄 • 가중치 없는 방향그래프 G 모든 i와 j에 대하여 i->j의 경로 존재여부 결정 • 이행적 폐쇄(transitive closure) : 양의 경로길이 요구 • 반사 이행적 폐쇄(reflexive transitive closure) : 음이아닌 경로 길이만을 요구
6.4 최단경로와 이행적 폐쇄 [정의] 이행적폐쇄행렬 A+ • 방향그래프 G에서 i->j로의 길이 > 0인 경로존재 : A+[i][j]=1 그렇지 않으면 :A+[i][j]=0 [정의] 반사 이행적폐쇄행렬 A* • 방향그래프 G에서 i->j로의 길이 >= 0인 경로존재 : A*[i][j]=1 그렇지 않으면 :A*[i][j]=0
과제물 • 최단경로 알고리즘 프로그래밍