2. 과제수행일지
소속 조원
A1 조장 : 정의수 자료조사 : 김선형, 김지욱 프로그래밍 : 정의수, 조경상
과제수행기간 5일 약 20시간
I. 계획의 작성
연구제목 최단거리 찾기
그래프의 구조와 사용 방법을 알고 최단거리 찾기 과제를 수행하면서 그래프에 대하
연구배경
여 이해한다.
C로 쓴 자료구조론/HOROWITZ, Sahni, Anderson-Freed 저/이석호 역/
참고 서적
교보문고
그래프의 개념과 구현하는 방법 및 최단거리 찾기에 관한 참고 자료
http://blog.nextcube.pe.kr/190
참고자료 http://blog.naver.com/kiho0530?Redirect=Log&logNo=150139178186
http://ko.wikipedia.org/wiki/%ED%94%8C%EB%A1%9C%EC%9D%B4%
참고 URL EB%93%9C-%EC%99%80%EC%85%9C_%EC%95%8C%EA%B3%A0%EB%
A6%AC%EC%A6%98 //플로이드 와셜 알고리즘
http://alg.pknu.ac.kr/wordpress/floyd-warshall-algorithm // 플로드
이 와셜 알고리즘
http://thinkberry.co.kr/3376// 다익스트라 알고리즘
II. 계획의 실행
첫째 날 2012년 5월 29일 화요일
오늘의 작업 조원의 업무 분담 및 과제에 대한 이해와 숙지
조장 :
자료조사 : 김선형, 김지욱
프로그래밍 : 정의수, 조경상
토의 내용
업무를 분담하고 주어진 업무에 맞게 다음 회의시간 까지 각자 조사를 하기로 했다.
그리고 회의에 참석하지 못한 조원에게는 토의 내용을 전달하기로 했다.
과제준비에서 수업이나 토의에 참여하지 않는 조원이 한 명이라도 있을 경우에는 그만큼 다른 조원에
3. 느낀 점 게 피해가 생기고 과제 수행에 대한 부담이 좀 더 가중된다는 것을 알게 되었다.
둘째 날 2012년 5월 31일 목요일
오늘의 작업 그래프에 대한 이해와 숙지
과제 수행을 하기 위해 우선적으로 필요한 그래프에 대한 내용에 대해 토의를 하였다.
그래프란 연결되어 있는 객체간의 관계를 표현할 수 있는 자료구조 이다.
1. 그래프 구조
<그림1. 그래프>
그래프는 정점(vertex)와 간선(edge)로 이루어져 있다. 위 그림에서 1번부터 6번까지
의 동그라미 원을 정점(vertex)라 하고, 각 정점을 연결하는 선을 간선(edge)라 한다.
위 그림은 6개의 정점과 7개의 간선으로 이루어져 있다. 정점에 연결된 간선의 개수를
차수(degree)라 한다. 4번 정점은 3개의 차수를 가지고 있고, 6번 정점은 1개의 차수를
토의 내용 가지고 있다. 인접(Adjacent) 이란 한 정점에서 간선을 한번만 통해 갈수 있다면 해당
정점간은 인접한다 라고 한다. 1번 정점과 2번 정점은 인접하지만, 1번 정점과 4번 정
점은 인접하지 않는다.
<그림2. 무방향 그래프>
무방향 그래프는 방향성이 없는 간선으로 이루어진 그래프이다. 그러므로 (1, 2) 나
(2, 1)은 동일한 간선을 나타낸다.
4. <그림3. 방향 그래프>
하지만 방향 그래프는 간선에 방향성을 나타내어 정점간의 방향관계를 나타내는 그래
프 이므로 (1, 2) 와 (2, 1)은 서로 다른 간선이 된다. 그래서 방향 그래프는 차수를 내
차수(in-degree), 외차수(out-degree)로 구분하여 갖고 있다.
2. 그래프 표현(인접 행렬, 인접 리스트)
① 행렬
<그림4. 그림3의 그래프를 나타낸 행렬>
세로축이 출발 정점이고 가로축이 도착 정점이라 한다면, 첫 번째 1번 정점을 출발 정
점으로 각각의 정점들, 1번부터 4번 정점의 방향성을 나타낸 것이 1번 행이 된다.
1번 정점은 1번 정점으로 가는 길이 없으므로 0,
1번 정점은 2번 정점으로 가는 길이 없으므로 0,
1번 정점은 3번 정점으로 가는 길이 있으므로 1,
1번 정점은 4번 정점으로 가는 길이 있으므로 1,
이렇게 된다.
5. ② 리스트
<그림5. 그림3의 그래프를 나타낸 리스트>
1번 정점은 3번, 4번 정점으로 갈수 있고
2번 정점은 1번, 3번 정점으로 갈수 있다.
위와 같이 조사한 내용을 바탕으로 그래프 구조에 대해 이해하고 과제 진행을 위한 알
고리즘을 구성하기로 하였다.
과제준비에서 조원 모두 적극적인 자세로 자료를 조사했고 조사 내용 중 그래프에서 모든 정점 간의
느낀 점 최단거리를 구하는 알고리즘은 “플로이드 와셜 알고리즘”을 좀 더 조사해 보기로 했다.
셋째 날 2012년 6월 4일 월요일
오늘의 작업 최단거리 찾기 과제의 프로그램 소스 초안 코딩
<플로이드 와셜 알고리즘>
void floyd(){
for(int i = 1; i <= N; i++){
for(int j = 1; j <= N; j++){
d[i][j] = w[i][j]; //k=0
}
}
for(int k = 1; k <= N; k++){
for(int i = 1; i <= N; i++){
for(int j = 1; j <= N; j++){
if(d[i][j] > d[i][k] + d[k][j]){
토의 내용 d[i][j] = d[i][k] + d[k][j];
및 b[i][j] = k;
소스 초안 }
}
}
}
}
<소스 초안>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
6. int** floyd(int* W[], int* P[], int n);//플로이드 함수
int** make_array(int n); // n x n 행렬의 메모리를 할당후 배열의 시작 주소를 반환
int main(void)
{
int i, j, temp, n=NULL;
int **ary, **t_ary, **D;
char buf[100];
char *ptr;
int state;
FILE *f;
f=fopen("test.txt","r");
if((f = fopen("test.txt", "r"))==NULL) //파일 읽기 실패시 종료
{
printf("File didn't openn");
exit(1);
}
for( ; ; ) //파일을 읽어와서 각각의 배열에 알맞게 대입
{
if(fgets(buf, sizeof(buf), f)==NULL) break;
if(n==0) //파일에서 처음 숫자가 나오면 n의 값에 넣어주고 그 수 만큼 후에
동적할당으로 이차원 배열 생성
{
for(i=0; i<strlen(buf)-1; i++)
n += (buf[i]-48)*pow(10, strlen(buf)-i-2);
ary = make_array(n);
for(i=0; i<n; i++) //이차원 배열에 모두 0을 대입
{
for(j=0; j<n; j++)
ary[i][j]=0;
}
}
else //파일에서 노드와 가중치를 읽어와 가중치를 이차원 배열에 대입
{
ptr = strtok(buf, ", ");
while(ptr != NULL)
{
if(ptr[0]>=48 && ptr[0]<=57)
{
temp=strtol(ptr, &ptr, 10);
ary[buf[0]-65][buf[1]-65]=temp;
ary[buf[1]-65][buf[0]-65]=temp;
}
ptr = strtok(NULL, ", ");
}
7. }
}
t_ary = make_array(n+1);
D = floyd(ary, t_ary, n);
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
printf("%d ", ary[i][j]);
printf("n");
}
printf("n");
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
printf("%d ", D[i][j]);
printf("n");
}
// printf("Choose start vertex(%c ~ %c) : ",
state = fclose(f); //파일이 제대로 닫혔는지 확인
if(state!=0)
{
printf("not close");
exit(1);
}
free(ary);
return 0;
}
int** floyd(int* W[], int* P[], int n)
{
int i, j, k;
int** D;
D = make_array(n);
for (i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
D[i][j] = W[i][j];// D 행렬 = W 행렬
}
for (k = 0; k < n; k++)
{
for (i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
8. if (D[i][j] > D[i][k] + D[k][j]) {
P[i+1][j+1] = k+1; // 경로를 구하기 위한 배열
D[i][j] = D[i][k] + D[k][j];
}
}
}
}
return D;
}
int** make_array(int n) // n x n 행렬의 메모리를 할당후 배열의 시작 주소를 반환
{
int i;
int** array;
array = (int**)malloc(sizeof(int*)*n);
for(i = 0; i < n; i++)
array[i] = (int*)malloc(sizeof(int)*n);
return array;
}
<출력 부분 미완성>
<test.txt 내용>
4
AB 10
CD 1
BC 3
AC 5
AD 9
위의 플로이드 와셜 알고리즘을 사용하여 각 노드의 최단거리를 구하는 인접 행렬까지 만
문제점 들고 출력 부분 알고리즘을 구상하였지만 노드가 5개 이상이 되면 최단거리를 구하는 인
접행렬이 오류가 나서 이상한 값들이 출력되었다.
플로이드 와셜 알고리즘을 사용하지 않고 다익스트라 알고리즘을 사용해 보기로 하였지만
해결 방안
시간이 부족하여 구현을 하지 못하였다.
III. 반성
그래프를 이용하여 최단거리를 구하는 알고리즘이 생각 외로 다양해서 무척 놀라웠다. 단
과제를 마치면서
지 시간적 여유가 좀 더 있었고 문제점을 빨리 찾았다면 구현을 시킬 수 있었을 것이라
느낀 점
생각이 들며 그 점이 매우 아쉽다.
9. 자료조사를 해서 공부한 자료들을 실제로 소스에 적용시키는 과정이 너무 더뎠다. 그리고
기타 출력부분에 대해서 완전하게 이해를 하는 것이 시간이 걸렸다. 이런 요인들로 인해 소스
구현이 미완성이 되었던 것 같다.