다익스트라(Dijkstra) 알고리즘

Download Report

Transcript 다익스트라(Dijkstra) 알고리즘

다익스트라(Dijkstra) 알고리즘
1조: 박진우 ,정용양 ,송규석
다익스트라란?

(1959 년에 만들어진) Dijkstra 의 알고리즘은 오래된 널리 알려진 알고

리즘입니다. 이 알고리즘은

간선에 가중치(weight)를 가진 그래프에서 최단 경로를 찾을 수 있게 해

줍니다.또한 이 알고리즘은 음수값을 갖지 않는 간선(edge)을 가지는

가중치(weight)가 있는 유향 그래프(directed graph)에 사용됩니다. 이

러한 특별한 수행환경을 가짐과 동시에 그래프는 연결(connected)되어있

어야만 합니다.
간선을 가진 유향 그래프이며 정점들간의
알고리즘 원리








시작 정점으로부터 임의의 정점 X까지의 거리가 현재 다른 정점까지 가는
것보다 작다고 가정하자. 그렇다면 다른 정점을 경유해서 갈 경우, 그냥 임
의의 정점 X까지 가는 것이 무조건 더 작을 것이다. (가정에 의해, 그리고 모
든 가중치는 양수이다)
위에 그림에서 보면, S->X는 가장 짧은 간선이다. 그러므로 S->T라는 간
선은 S->X보다 클 것이다. 또한 T->X는 물론 양수이므로 결국, (S->T +
T->X) >(S->X)임을 알 수 있다. 물론, 가장 가중치가 작은 간선이 경로로
바뀐다 해도 이 원리는 변하지 않는다. 다익스트라는 이 원리를 이용한 알고리즘
이다.
최단거리 구할 시 알아야 할
다익스트라 알고리즘




[1] 시작 정점에서 가장 인접한 정점을 찾는다. 그 정점까지 거리
가 최단거리이다. 지금까지 최단거리가 알려진 정점은 2개(자
기 자신과 지금 찾은 정점)가 된다. 최단거리가 알려진 정점들
의 집합을 S라 하자.
[2] 집합 S에 포함되지 않은 정점 중에서 시작 정점으로부터 가장

가까운 정점을 찾는다. 이 새로운 정점은 집합 S에 바로 이웃

한 정점들 중 하나일 것이다. 그 정점까지 거리는 최단거리이

며, 그 정점을 집합 S에 포함시킨다.
[3] 새로운 정점이 없을 때까지, 즉 모든 정점이 집합 S에 포함될

때까지 []의 과정을 반복한다.

다익스트라 방법의 적용 예
∞
2
2
0
a
4
b
3
3
2
1
c
f
1
4
2
3
d
1
e
6
∞
3
(a)

A에서부터 최단경로를 계산한다
∞

B를 택한 것은 A에서 가장 가깝기 때문이다.
6
2
4
b
2
0
1
3
4
d
∞
3
3
2
a
c
f
1
2
1
e
5
3
(b)
6
2
2
0
a
4
b
c
3
3
2
1
5
f
1
4
∞
2
3
d
1
e
6
4
3
(c)


D를 선택한 이유는 B속한 정점을 거쳐서 A로부터 가는
최단경로이기 때문

E를 선택한 이유는 D와B를 속한 정점을 거쳐서 A로부터
 가는 최단경로이기 때문
5
2
2
0
a
4
d
c
3
3
2
1
3
4
b
f
1
2
1
e
4
3
(d)
6


C를 선택한 이유는 D,B,E를 속한 정점을 거쳐서 A로부터
가는 최단경로이기 때문
2
4
b
2
0
1
c
3
3
2
a
5
f
1
4
2
3
d
1
e
4
3
(e)
6
8


A에서 F로 가는 최단경로는{a, b, d, e, c, f}
이다.
5
2
4
b
2
0
1
3
4
d
3
3
2
a
c
f
1
2
1
e
4
3
(f)
6
다익스트라 알고리즘을 사용할 시
알아야 할 배열 정의 
s = 입력받는 출발점입니다

e = 입력받는 도착점입니다



data[i][j] = i정점부터 j정점까지의 거리(이건 최단거리가 아닙
니다. 하나의 간선을 거쳐서 가야 합니다) 그리고 i정점과 j정점
이 직접적으로 연결되어 있지 않으면 MAX값을 넣어줍니다

distance[i] = s(출발점)에서 i번째 정점까지의 최단거립니다.

v[i] = i번째 정점이 체크되었는지를 나타냅니다 (1 : 체크)

via[i] =s정점부터 i번째 정점으로 가는 최단경로에서 i번째 경
로의 바로 전 정점의 번호입니다

알고리즘…

#include<stdio.h>



int
int
int
열
int













data[5][5]={0,};
dist[5]={0,};
processed[5]={0,};
n,s,e;
// 인접행렬을 저장하는 배열
// 시작점으로부터의 거리를 저장하는 배열
// 그 노드가 이미 처리되었는지 여부를 저장하는 배
// n : 노드수
// s : 시작점
// e : 끝점
void input()
{
FILE *in=fopen("dijkstra.in","r");
int i,j;
fscanf(in,"%d",&n);
// 노드수와 시작점, 끝점 그리고 인접행렬을 입력받음
fscanf(in,"%d %d",&s,&e);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
fscanf(in,"%d",&data[i][j]);
}


void process()
{

int i,j;

int min,minx;



processed[s]=1;

for(i=1;i<=n;i++)
dist[i]=data[s][i];












// min : 아직 선택하지 않은 점들중 가장 가
까운 점까지의 거리를 저장하는 변수
// minx : min값의 거리에 있는 점의 노드번
호를 저장하는 변수
// 시작점에서 거리를 모두 초기화.. 즉, 아무
점도 거치지 않고 갈때의 거리 저장
for(i=1;i<=n;i++)
{
min=9999;
// 최소값을 줄임
for(j=1;j<=n;j++)
if ((processed[j]==0)&&(dist[j]<min))
{
// '현재 선택하지 않은 점'들중에서 가장 가까운 점을 찾음.
min=dist[j];
minx=j;
}











processed[minx]=1;
if (minx==e) break;
for(j=1;j<=n;j++)





void output()
{
FILE *out=fopen("dijkstra.out","w");
fprintf(out,"%d",dist[e]);
}






void main()
{
input();
process();
output();
}
// 가장 가까운 점을 선택한 것으로 저장.
// 만약 가장 가까운 점이 끝점이라면 루프 종료
// 시작점->가장 가까운 점 거리와 가장 가까운 점->j
까지의 거리가 시작점->j보다
// 작으면 dist[j]를 시작점->가장 가까운 점 + 가
장 가까운점->j 의 값으로 갱신
if (dist[j]>data[minx][j]+dist[minx])
dist[j]=data[minx][j]+dist[minx];
}
}

END…