Transcript
Page 1: Project#5 최단거리 찾기 D0 Hwp

project #5

최단거리 찾기

자료구조 D0

조장

김 현호20093468

조원

서 상현20113293

김 창헌20093463

최 고봉20093530

김 정무20113281

Page 2: Project#5 최단거리 찾기 D0 Hwp

순서

조원별 업무분담•

일정 계획•

자료조사 및 문제 파악•

알고리즘 계획•

소스구현•

잘된 점 잘 못된 점/•

Page 3: Project#5 최단거리 찾기 D0 Hwp

업무 분담-

조장 김 현호:

자료 조사 김 창헌 김 정무 서 상현: , ,

프로그래밍 최 고봉:

일정-

업무분담 및 알고리즘 조사5/29

사용할 알고리즘 채택 및 알고리즘 공부5/31

Page 4: Project#5 최단거리 찾기 D0 Hwp

자료 조사 및 문제 파악

자료조사-그래프 개념 정리그래프 개념 정리그래프 개념 정리그래프 개념 정리1.1.1.1.

그래프(1)  

그래프란? 그래프란 연결되어 있는 객체간의 관계를 표현할 수 있는 자료구조

그래프 용어그래프 용어그래프 용어그래프 용어a.정점(Vertex)노드 라고도 하며 객체를 나타내며 데이터가 저장된 곳(Node) , .

b.간선(Edge)정점을 연결하는 것.

차수c. (Degree)하나의 정점에 닿아있는 간선의 수.번 정점의 차수는 이 됩니다1 3 .

인접d. (Adjacent)한 정점에서 간선을 한번만 통해 갈수 있다면 해당 정점간은 인접하다라고 합니다.번 정점과 번 정점은 인접하지만 번 정점과 번 정점은 인접하지 않습니다1 2 , 1 4 .

무향 그래프e. (Undirected Graph)말 그대로 방향성이 없는 간선으로 이루어진 그래프

Page 5: Project#5 최단거리 찾기 D0 Hwp

유향 그래프f. (Directed graph)간선에 방향성을 나타내어 정점간의 방향관계를 타나내는 그래프

번 정점은 번과 번으로 갈수 있지만 번 정점은 번 정점과 번 정점으로만 갈 수2 3 1 , 1 3 4있습니다.

완전 그래프g. (Complete Graph)모든 정점이 인접한 상태인 그래프.모든 정점이 서로 간선으로 연결된 그래프이며 개 정점이 있다면 모든 정점이 개의, n n-1간선을 갖는 그래프.

Page 6: Project#5 최단거리 찾기 D0 Hwp

그래프 저장 방법  1)

배열로 저장1.

정점의 개수가 이라면 배열로 표현- n  n*n

행은 진출 방향을 열은 진입방향을 나타냄-

무 방향 그래프 간선 로 표시- : -1

연결 리스트로 저장2.  

각 정점에서 진출하는 리스트를 저장-

 

그래프 탐색3.  

Page 7: Project#5 최단거리 찾기 D0 Hwp

깊이 우선 탐색a.   

정점을 탐색할 때 아래쪽으로 먼저 탐색한다- .

넓이 우선 탐색b.  

특징 정점을 기준으로 가로로 먼저 탐색한다- .

정렬4. ( Sort ) 

자료를 일정한 기준에 따라 순서 있게 정리 하는 것-

 

정렬 위치에 따른 구분a.  

내부 정렬 

주 기억 장치 안에서 정렬하는 방법-  

외부 정렬 

보조 기억 장치를 활용해서 정렬하는 방법-  

정렬 순서에 따른 구분b.  

오름 차순 정렬 

값이 작은 것 부터 큰 순서대로 정렬하는 방법-  

내림 차순 정렬 

Page 8: Project#5 최단거리 찾기 D0 Hwp

값이 큰 것부터 작은 순서대로 정렬하는 방법-  

정렬 알고리즘c.  

버블 정렬 

가장 간단한 알고리즘으로 인접한 두 개의 자료를 비교한 뒤 그 크기에- ,

따라 자료 위치를 바꾸어 정렬 

선택 정렬 

하나의 기준 자료를 선택한 후 그 다음 자료에서부터 끝의 자료까지 하-

나씩 비교해 가는 방식으로 간단한 반면 속도가 느리다. 

삽입 정렬 

이미 자료가 정렬되어 있는 상태에서 새로운 자료를 삽입할 경우 또는-

거의 정렬이 되어 있는 자료일 경우 효율적 

셀 정렬

주어진 자료를 특정 길이만큼씩 서브파일로 나눈다음 각 서브파일을 삽-

입 정렬 형식으로 처리하고 서브파일 길이를 조금씩 줄여가면 최종 결과

가 나온다. 

퀵 정렬 

자료 중에서 특정한 하나의 자료를 제어키로 정한 뒤 그 키를 기준으로- ,

그 보다 작은 값은 왼쪽에 큰 값은 오른쪽에 배치한다, . 

힙 정렬 

힙이라는 자료 구조를 이용 완전이진 트리 형태를 가지고 있는 각 노드- ' ' ,

값이 자식 노드들의 값보다 적지 않아야 한다. 

병합 정렬 

셀 정렬의 반대 개념으로 자료를 개씩 하나의 그룹으로 묶어 그룹 내부- 2

를 정렬한 후 다시 그룹 두개씩을 묶어 정렬한다, .

출처 : http://blog.naver.com/s2miniwish?Redirect=Log&logNo=158638753

다익스트라 알고리즘다익스트라 알고리즘다익스트라 알고리즘다익스트라 알고리즘2.2.2.2.

정의(1)

출발점에서 시작하여 거리가 최소인 정점을 선택해 나가면 최단 경로를 구할 수 있다는1)

알고리즘의 일종이다greedy .

사용(2)

시작 정점에서 인접한 정점 중 가장 비용이 최소인 정점을 선택하여 지나온 경로 에 포1) S

함 시킨다.

Page 9: Project#5 최단거리 찾기 D0 Hwp

미 선택 정점 중에서 선택한 최소 거리 정점 거리 는 에서 까지의 최단경2) w Dist[w] S w

로의 길이다.

더 짧은 새로운 길을 발견 할 때 의 누적 길이를 갱신한다3) Dist[w] .

갱신시에 지나온 경로를 역 추적 하기위해 배열에 이전 를 기억한다4) previous[n] vertex .

다익스트라 작동 원리(3)

Page 10: Project#5 최단거리 찾기 D0 Hwp

벨만포드 알고리즘벨만포드 알고리즘벨만포드 알고리즘벨만포드 알고리즘3.3.3.3.

정의(1)

간선의 가중치를 음의 값을 허용1)

음의 은 허용하지 않음2) cycle

의 가중치의 합이 일 경우 여러 번 수행 할수록 비용이 감소:cycle <0

결국 의 최단 경로 생성되므로 최단 경로의 의미가 없음- .∞

개요(2)

간선을 최대 개 사용하는 최단 경로1) 1

간선을 최대 개 사용하는 최단 경로2) 2

간선을 최대 개 사용하는 최단 경로3) 3

정점의 개수 만큼 반복4) ( |v|-1 )

플로이드 알고리즘플로이드 알고리즘플로이드 알고리즘플로이드 알고리즘4.4.4.4.개요(1)

알고리즘의 시간복잡도가 인데 반해 플로이드 알고리즘은 이다 이것만Dijkstra O(n^2) O(n^3) .봐서는 알고리즘이 더 느릴 것이라고 생각하기 쉽다 하지만 알고리즘이 한Floyd . Dijkstra번의 루프를 돌 때마다 하는 일이 많다보니 복잡하다보니 실제로는 가 빠른 경우가( ) Floyd상당히 많다.

동작원리 자체는 매우 간단하다 에서 로 갈 수 있는 경로가 있고 또한 에서 로 갈 수. A B , B C

있는 경로가 있다고 한다면 결국 에서 로 갈 수 있는 경로가 있다고 할 수 있다 만약A C .

에서 로 직접 갈 수 있는 경로가 원래 존재했는데 직접 갈 때의 비용이 를 거쳐 로A C ' ' B C

가는 것보다 많이 든다고 하자 그러면 플로이드 알고리즘에서는 에서 로 가는 것을. A C

폐기하고 에서 를 거쳐 로 가는 최단거리 로 업데이트를 하게 된다A B C ' ' .

알고리즘알고리즘알고리즘알고리즘5.A*5.A*5.A*5.A*

개요(1)

에이 스타 알고리즘은 년에 만들어진 것으로 탐색을 수행하는데 있어 매우 효과적인A*( ) 1968 ,

알고리즘이며 다양한 종류의 문제들을 해결하는데 사용되어 왔다 알고리즘은 출발지점에서. A*

목표지점까지 가장 비용이 낮은 보통 가장 짧은 경로를 찾는데 다음과 같이( ) , 'f = g + h'

계산값을 사용하여 다음으로 이동할 경로를 결정한다.

는 목표 로서 시작노드로부터 이 노드까지 오는 데 드는 비용이다 시작노드에서 이g goal( ) , .

위치까지 오는 경로들은 여러 개가 있을 수 있는데 이 노드는 그 경로들 중 특정한 하나를,

의미한다.

는 휴리스틱 으로 이 노드에서 목표까지 가는데 드는 추정된 비용이다 이때 는h heuristic( ) , ' ' . h

휴리스틱을 의미하며 휴리스틱이란 경험에 기초한 추측을 뜻한다 이것이 추측된 비용인, ' ' . ' '

이유는 목표까지의 실제 비용을 아직은 알지 못하기 때문이다 휴리스틱을 계산하는데 여러.

Page 11: Project#5 최단거리 찾기 D0 Hwp

가지 방법이 있을 수 있지만 일반적으로 현재 위치에서 목표까지의 일직선 거리값을,

사용한다.

는 적합도 로서 와 의 합이고 이 노드를 거쳐 가는 경로의 비용에 대한 최선의f fitness( ) , g h

추측을 의미한다 값이 낮을수록 이 경로가 최단 경로일 가능성이 크다. f .

현재위치에서 다음의 어떤 노드로 이동할 것인가를 결정하는 방법은 다음과 같다 현재위치에.

연결된 다음 노드가 여러개일 경우 각각의 다음 노드마다 시작위치에서 다음 노드까지의,

거리와 그 노드에서 목표까지의 추정된 휴리스틱 값을 더한 값들을 계산하여 값이 가장 작은f , f

노드쪽으로 이동하는 것이 목표까지의 가장 짧은 경로가 될 가능성이 높다 이렇게 값이 가장. f

작은 노드들을 선택하여 탐색을 수행하다 목표노드에 도착하면 탐색을 종료한다.

문제 파악-정의된 모든 노드에서 모든 노드로의 패스 중에서

값이 가장 낮은 패스 개를 출력한다weight 3 .

이때 가중치의 합 또한 같이 출력되게 한다.

알고리즘 계획-플로이드 알고리즘을 이용하여 정의된 모든 노드에서 다른 모든 노드로의 패스를 구한다음

값이 가장 낮은 패스 개를 가중치의 합과 함께 출력하도록 한다weight 3 .

소스 구현-#include <stdio.h>

#include <stdlib.h>

int **graph;

int ***result;

int ***max_tmp;

char *node;

void InitGraph(int n);

void PrintPath(int i, int j);

void UnInitGraph(int n);

Page 12: Project#5 최단거리 찾기 D0 Hwp

void main(int argc, char* argv[]) {

FILE* input;

int n, k, i, j, x;

int weight;

char name[3];

if ( argc != 2 || strlen(argv[1]) == 0) {

printf("Usage : %s filename\n" , argv[0]);

getch();

return 0;

}

input = fopen(argv[1],"r");

if (!input) {

fprintf(stderr,"Can not open a file. : %s \n",argv[1]);

getch();

exit(1);

}

fscanf(input,"%d",&n);

InitGraph(n);

printf("%d\n",n);

for( i = 0 ; i < n ; i++ ) {

graph[i][i] = 0;

result[i][i][0] = 0;

result[i][i][1] = 0;

result[i][i][2] = 0;

}

while ( !feof(input) ) {

fscanf(input,"%s",name);

for( i = 0 ; i < n ; i++ ) {

if( node[i] == name[0] ) break;

if( node[i] == 0 ) {

node[i] = name[0];

break;

}

}

for( j = 0 ; j < n ; j++ ) {

if( node[j] == name[1] ) break;

if( node[j] == 0 ) {

node[j] = name[1];

break;

}

Page 13: Project#5 최단거리 찾기 D0 Hwp

}

fscanf(input,"%d",&weight);

graph[i][j] = weight;

graph[j][i] = weight;

result[i][j][0] = weight;

result[j][i][0] = weight;

printf("%c%c %d\n",node[i],node[j],graph[i][j]);

}

printf("\n");

for( x = 0 ; x < 3 ; x++ ) {

for( k = 0 ; k < n ; k++ ) {

for( i = 0 ; i < n ; i++ ) {

for( j = 0 ; j < n ; j++ ) {

if( x > 0 ) {

if( result[i][j][x-1] < result[i][k][0] + result[k][j][0] ) {

if( result[i][j][x] > result[i][k][0] + result[k][j][0] ) {

result[i][j][x] = result[i][k][0] + result[k][j][0];

}

}

}

else {

if( result[i][j][0] > result[i][k][0] + result[k][j][0] ) {

result[i][j][x] = result[i][k][x] + result[k][j][x];

}

}

}

}

}

}

for( i = 0 ; i < n ; i++ ) {

for( j = 0 ; j < n ; j++ ) {

if( result[i][j][0] > result[i][j][1] ) {

if( result[i][j][0] > result[i][j][2] ) {

if( result[i][j][1] > result[i][j][2] ) {

x = result[i][j][0];

result[i][j][0] = result[i][j][2];

result[i][j][2] = x;

}

else {

x = result[i][j][0];

result[i][j][0] = result[i][j][1];

Page 14: Project#5 최단거리 찾기 D0 Hwp

result[i][j][1] = result[i][j][2];

result[i][j][2] = x;

}

}

else {

x = result[i][j][0];

result[i][j][0] = result[i][j][1];

result[i][j][1] = x;

}

}

else {

if( result[i][j][0] < result[i][j][2] ) {

if( result[i][j][1] > result[i][j][2] ) {

x = result[i][j][1];

result[i][j][1] = result[i][j][2];

result[i][j][2] = x;

}

}

else {

x = result[i][j][0];

result[i][j][0] = result[i][j][2];

result[i][j][2] = result[i][j][1];

result[i][j][1] = x;

}

}

}

}

printf(" Graph weight array :\n");

for (i = 0; i < n; i++) {

for(j = 0; j < n; j++) {

if( graph[i][j] == 30000 )

printf(" oo");

else

printf("%3d", graph[i][j]);

}

printf("\n");

}

printf("\n");

for( x = 0 ; x < 3 ; x++ ) {

printf(" Shortest Path %d weight array :\n",x+1);

for ( i = 0 ; i < n ; i++) {

Page 15: Project#5 최단거리 찾기 D0 Hwp

for( j = 0 ; j < n ; j++) {

if( result[i][j][x] == 30000 ) {

result[i][j][x] = result[i][j][x-1];

printf("%3d", result[i][j][x]);

}

else

printf("%3d", result[i][j][x]);

}

printf("\n");

}

printf("\n");

}

UnInitGraph(n);

fclose(input);

printf( 계속하시혀면 아무키나 누르세요" .....“);

getch();

}

void InitGraph(int n) {

int i,j;

graph = (int **)malloc(n*sizeof(int *));

result = (int ***)malloc(n*sizeof(int **));

max_tmp = (int ***)malloc(n*sizeof(int **));

node = (char *)malloc(n*sizeof(char));

for( i = 0 ; i < n ; i++ ) {

graph[i] = (int *)malloc(n*sizeof(int));

result[i] = (int **)malloc(n*sizeof(int *));

max_tmp[i] = (int **)malloc(n*sizeof(int *));

node[i] = 0;

for( j = 0 ; j < n ; j++ ) {

result[i][j] = (int *)malloc(3*sizeof(int));

max_tmp[i][j] = (int *)malloc(2*sizeof(int));

graph[i][j] = 30000;

result[i][j][0] = 30000;

result[i][j][1] = 30000;

result[i][j][2] = 30000;

max_tmp[i][j][0] = 30000;

max_tmp[i][j][1] = 0;

}

}

}

Page 16: Project#5 최단거리 찾기 D0 Hwp

void UnInitGraph(int n) {

int i,j;

for( i = 0 ; i < n ; i++ ) {

for( j = 0 ; j < n ; j++ ) {

free(result[i][j]);

free(max_tmp[i][j]);

}

free(graph[i]);

free(result[i]);

free(max_tmp[i]);

}

free(graph);

free(result);

free(max_tmp);

free(node);

}

Page 17: Project#5 최단거리 찾기 D0 Hwp

결과-

Page 18: Project#5 최단거리 찾기 D0 Hwp
Page 19: Project#5 최단거리 찾기 D0 Hwp

잘된 점-각자 역할에 맞게 할 일들을 잘 처리해 주었기에 이번 프로젝트도 무사히 마칠 수가 있었다.

잘 못된 점-처음부터 문제를 파악하기 힘들었다 모든 노드를 정의하고 사용자가 임의로 지정한 시작 노.

드와 끝 노드 사이의 최단 패스 개를 출력하는 프로그램을 짜려했으나 잘 못된 판단이었고 시3 ,

간을 소비했다.

고쳐야 할 점-각자 이때까지 조에서 나름대로의 역할을 수행해 왔기 때문에 역할에 맞는 일처리가 알맞게 이

루어 졌으나 문제파악에 대한 부족함이 보였다 그로인해 아까운 시간을 많이 허비하게 되었.

다 다음 프로젝트에서는 첫 회의 때에 문제파악부터 제대로 이루어 져야 할 것이다. .


Recommended