반응형

가중치는 서울 교통 공사 사이버 스테이션(http://www.seoulmetro.co.kr/kr/cyberStation.do) 에서

나오는 거리(km)를 기반으로 하였음

 

서울교통공사 사이버 스테이션

요일 선택 평일 토요일 공휴일 시 선택 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 분 선택 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 5

www.seoulmetro.co.kr

 

/*
다익스트라 알고리즘

*/

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

#define INF 1000 //무한, 인접해있지 않은 경우 무한으로 처리, 
//여기서는 가중치를 다 더해서 나올수 없는 큰수 1000으로 하였음

//지하철 노선도
#define VERTEX_COUNT 13
int adj[VERTEX_COUNT][VERTEX_COUNT] =
{
	{INF, 9, INF, 8, INF, INF, 6, 10, INF, INF, INF, INF, INF},      // 0. 종로3가 : 종로5가, 종각, 을지로3가, 을지로4가
	{9, INF, 8, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF},   // 1. 종로5가 : 종로3가, 동대문
	{INF, 8, INF, INF, INF, INF, INF, INF, 7, INF, INF, INF, INF},   // 2. 동대문 : 종로5가, 동대문역사문화공원
	{8, INF, INF, INF, 10, INF, INF, INF, INF, INF, INF, INF, INF},  // 3. 종각 : 종로3가, 시청
	{INF, INF, INF, 10, INF, 7, INF,  INF, INF, 11, INF, INF, INF},  // 4. 시청 : 종각, 을지로 입구, 서울역 
	{INF, INF, INF, INF, 7, INF, 8,  INF, INF, INF, INF, INF, INF},  // 5. 을지로입구 : 시청, 을지로3가
	{6, INF, INF, INF, INF, 8, INF,  6, INF, INF, INF, INF, 7},      // 6. 을지로3가 : 종로3가, 을지로입구, 을지로4가, 충무로
	{10, INF, INF, INF, INF, INF, 6, INF, 10, INF, INF, INF, INF},   // 7. 을지로4가 : 종로3가, 을지로3가, 동대문역사문화공원
	{INF, INF, 7, INF, INF, INF, INF, 10, INF, INF, INF, INF, 13},   // 8. 동대문역사문화공원 : 동대문, 을지로4가, 충무로
	{INF, INF, INF, INF, 11, INF, INF,  INF, INF, INF, 9, INF, INF}, // 9. 서울역 : 시청, 회현
	{INF, INF, INF, INF, INF, INF, INF, INF, INF, 9, INF, 7, INF},   // 10. 회현 : 서울역, 명동
	{INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, 7, INF, 7},   // 11. 명동 : 회현, 충무로
	{INF, INF, INF, INF, INF, INF, 7, INF, 13, INF, INF, 7, INF}     // 12. 충무로 : 을지로3가, 동대문역사문화공원, 명동
};

enum eStation
{
	종로3가,
	종로5가,
	동대문,
	종각,
	시청,
	을지로입구,
	을지로3가,
	을지로4가,
	동대문역사문화공원,
	서울역,
	회현,
	명동,
	충무로
};

char* vertexToStationName(int _vertexIndex); //정점 인덱스 -> 문자열 정점이름

//경로 확인 하기 위한 구조체, 간선의 시작점과 끝점을 의미
typedef struct _tagRoutePair
{
	int ParentV; //시작점
	int ChildV; //끝점
} ROUTEPAIR;

void Dijkstra(int _startV, int _endV)
{
	bool visited[VERTEX_COUNT] = { 0 }; //방문기록
	int distance[VERTEX_COUNT]; //시작점에서 각정점까지의 최소 가중치(최단거리) 기록
	ROUTEPAIR routePairs[VERTEX_COUNT] = { 0 }; //경로확인을 위한 간선 저장 배열
	
	//최소가중치 기록 배열 초기화
	for (int i = 0; i < VERTEX_COUNT; i++)
	{
		distance[i] = INF;
	}
	//distance[_startV] = 0;

	//주변 정점들과의 최소 가중치 기록하기
	for (int i = 0; i < VERTEX_COUNT; i++)
	{
		if (adj[_startV][i] != INF)
		{
			distance[i] = adj[_startV][i];
		}
	}
	visited[_startV] = true;
	routePairs[_startV].ParentV = _startV;

	int curretV = _startV; 
	for(int i = 0; i < VERTEX_COUNT - 1; i++)
	{
		int min = INF;
		int minIdx = curretV;

		for (int i = 0; i < VERTEX_COUNT; i++) //방문하지 않고, 최소 가중치 기록중 제일 낮은 가중치를 가지는 정점 찾기
		{
			if (!visited[i]) 
			{
				if (min > distance[i])
				{
					min = distance[i];
					minIdx = i; 
				}
			}
		}
		
		//기준 정점 초기화 및 방문 처리
		curretV = minIdx; 
		visited[curretV] = true;

		//방문한 정점을 기준으로 최소 가중치 배열 수정
		for (int i = 0; i < VERTEX_COUNT; i++)
		{
			if (!visited[i])
			{
				if (distance[curretV] + adj[curretV][i] < distance[i]) //이전경로 가중치 + 인접경로(새경로) 가중치
				{
					//경로 저장
					routePairs[curretV].ChildV = i;
					routePairs[i].ParentV = curretV;
				
					distance[i] = distance[curretV] + adj[curretV][i]; // 더 빠른 경우 초기화
				}
			}
		}
	
	}

	//반드시 adj 0번째 배열을 _start로 해야 아래로직이 무한루프 돌지 않고 잘동작함
	//_start 가 adj[0] 이 아닐 경우, 무한루프

	//경로 확인 하기
	int routeStack[VERTEX_COUNT] = { 0 };
	int RoutesCount = 0;
	routeStack[RoutesCount++] = _endV;
	int now = _endV;
	while(1)
	{
		if (routePairs[now].ParentV == _startV)
		{
			routeStack[RoutesCount++] = _startV;
			break;
		}
		now = routePairs[now].ParentV;
		routeStack[RoutesCount++] = now;
	}

	for (int i = RoutesCount - 1; i >= 0; i--)
	{
		
		if (i == RoutesCount - 1)
		{
			printf("%s 시작\n", vertexToStationName(routeStack[i]));
		}
		else if (i == 0)
		{
			printf("%s 도착\n", vertexToStationName(routeStack[i]));
		}
		else
		{
			printf("%s 방문\n", vertexToStationName(routeStack[i]));
		}
	}

}

char* vertexToStationName(int _vertexIndex)
{
	enum eStation e = _vertexIndex;
	switch (e)
	{
	case 종로3가:
		return "종로3가";
	case 종로5가:
		return "종로5가";
	case 동대문:
		return "동대문";
	case 종각:
		return "종각";
	case 시청:
		return "시청";
	case 을지로입구:
		return "을지로입구";
	case 을지로3가:
		return "을지로3가";
	case 을지로4가:
		return "을지로4가";
	case 동대문역사문화공원:
		return "동대문역사문화공원";
	case 서울역:
		return "서울역";
	case 회현:
		return "회현";
	case 명동:
		return "명동";
	case 충무로:
		return "충무로";
	default:
		return "없음";
	}
}


int main()
{
	Dijkstra(종로3가, 회현);
	
	return 0;
}

test 1

 

 

test 2

 

반응형
반응형

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

  • 에츠허르 비버 데이크스트라(Edsger Wybe Dijkstra) 1956년에 고안했으며 1959년 발표

  • 하나의 시작 정점에서 모든 다른 정점까지 최소비용의 인접정점을 선택하여 최단경로를 찾는 알고리즘

  • 입력 그래프에서 간선들의 가중치가 모두 0 이상인경우에 쓰임, 음수 가중치는 지원되지 않음(벨만-포드 알고리즘은 음수 가중치 허용)

  • 최단 경로는, 경로의 길이 순으로 정해짐

  • 다이나믹 프로그래밍 문제(큰문제를 작은 문제로 나누어 푸는 문제) 분류, 최단거리는 여러 개의 최단거리로 이루어져있기 때문이다

  • 가중치를 계산해서 효율적인 부터 방문하는 알고리즘

  • 인공위성 GPS 소프트웨어 등에서 가장 많이 사용됨


다익스트라 알고리즘 순서

  1. 시작점을 기준으로 아직 방문하지 않았고 인접한 정점들까지의 최소 가중치 정리

  2. 최소 가중치들 중에 아직 방문하지 않으면서 제일 작은 가중치를 가진 정점 선별

  3. 선별한 정점 방문, 방문한 정점 주변에 방문하지 않고 인접한 정점들을 파악

  4. 방문하지 않고 인접한 정점들중 시작점을 기준으로 해당 정점들까지의 최소 가중치 구해서 비교한뒤 빠르면 정리해놓은 최소 가중치를 수정, 느리면 그대로둠

(현재 기준점 까지의 최소가중치)+(인접한 정점까지의 가중치) < 현재 기록되어있는 최소 가중치

 

5. (전체 정점 개수 - 1(시작점)) 만큼 2~4 과정 반복

 

 

 

 

다익스트라 알고리즘 동작 과정 파헤치기

  1. 시작 정점을 기준으로 모든 정점에 이르는 최소 가중치(최단거리) 구해본다 이때 인접한 정점들은 가중치 계산이 되지만, 인접하지 않은 정점들은 어떤 점들을 경유해서 가야 될텐데, 아직 어떤점들을 지나갈지 모르므로 가중치가 무한(0 아닌 모든 가중치들의 합보다 일정한 하나의 )이라고 한다.

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

INF

8

INF

INF

6

10

INF

INF

INF

INF

INF

A_A A에서 A까지 도달하는 거리므로 사실상 0 다름없다.

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2. 인접한 정점들중 제일 낮은 가중치를 가진 정점(해당 예시에서는 G = 6) 방문처리 한다.

3. 방문한 정점을 기준으로 다시 인접하며, 아직 방문하지 않은 정점들을 찾는다,

이때 아까 인접하지 않았서 가중치를 무한으로 했던 정점들도 발견할 있는데, 지금 기준 정점(지금까지 제일 낮은 가중치) 경유하여 오게 되므로, 지금 기준 정점까지의 최소 가중치 + 해당 정점들 까지의 가중치 현재 기록되있는 최소가중치와 비교하여 빠르면 기입하고, 빠르지 않으면 그대로 둔다.

 

A_F = INF > A_G(6) + G_F(8) ? A_G(6) + G_F(8) : A_F(INF); //바뀜

A_H = 10 > A_G(6) + G_H(6) ? A_G(6) + G_H(6)  : A_H(10); //바뀜

A_M = INF > A_G(6) + G_M(7) ? A_G(6) + G_M(7) : A_M(INF); //바뀜

 

 

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

INF

8

INF

14

6

10

INF

INF

INF

INF

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

 

 

 

 

 

O

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4. 최소 가중치들 중에 아직 방문하지 않으면서 제일 작은 가중치를 가진 정점 선별

 

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

INF

8

INF

14

6

10

INF

INF

INF

INF

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

 

 

 

 

 

O

 

 

 

 

 

 

 

위표를 기준으로 D 제일 작고, 방문하지 않았으므로 D 선택됐다.

 

5. 선별한 정점(D) 방문, 방문한 정점 주변에 인접한 정점들을 파악

6. 인접한 정점들중 시작점을 기준으로 해당 정점들까지의 최소 가중치 구해서 비교한뒤 빠르면 정리해놓은 최소 가중치를 수정, 느리면 그대로둠

(현재 기준점 까지의 최소가중치)+(인접한 정점까지의 가중치) < 현재 기록되어있는 최소 가중치

 

A_E = A_E(INF) > A_D(8) + D_E(10) ? A_D(8) + D_E(10) : A_E(INF); //바뀜

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

INF

8

18

14

6

10

INF

INF

INF

INF

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

 

 

O

 

 

O

 

 

 

 

 

 

 

 

 

 

 

 

 

7.최소 가중치들 중에 아직 방문하지 않으면서 제일 작은 가중치를 가진 정점 선별

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

INF

8

18

14

6

10

INF

INF

INF

INF

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

 

 

O

 

 

O

 

 

 

 

 

 

B 선택됐다.

 

8. 선별한 정점(B) 방문, 방문한 정점 주변에 인접한 정점들을 파악

9. 인접한 정점들중 시작점을 기준으로 해당 정점들까지의 최소 가중치 구해서 비교한뒤 빠르면 정리해놓은 최소 가중치를 수정, 느리면 그대로둠

(현재 기준점 까지의 최소가중치)+(인접한 정점까지의 가중치) < 현재 기록되어있는 최소 가중치

A_C = A_C(INF) > A_B(9) + B_C(8) ? A_B(9) + B_C(8) : A_C(INF); //바뀜

 

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

17

8

18

14

6

10

INF

INF

INF

INF

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

 

O

 

 

O

 

 

 

 

 

 

 

 

 

 

 

 

10. 최소 가중치들 중에 아직 방문하지 않으면서 제일 작은 가중치를 가진 정점 선별

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

17

8

18

14

6

10

INF

INF

INF

INF

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

 

O

 

 

O

 

 

 

 

 

 

H 선택됐다

 

11. 선별한 정점(H) 방문, 방문한 정점 주변에 인접한 정점들을 파악

12. 인접한 정점들중 시작점을 기준으로 해당 정점들까지의 최소 가중치 구해서 비교한뒤 빠르면 정리해놓은 최소 가중치를 수정, 느리면 그대로둠

(현재 기준점 까지의 최소가중치)+(인접한 정점까지의 가중치) < 현재 기록되어있는 최소 가중치

 

A_I = A_I(INF) > A_H(10) + H_I(10) ? A_H(10) + H_I(10) : A_I(INF); // 바뀜

 

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

17

8

18

14

6

10

20

INF

INF

INF

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

 

O

 

 

O

O

 

 

 

 

 

 

 

 

 

 

 

 

 

13. 최소 가중치들 중에 아직 방문하지 않으면서 제일 작은 가중치를 가진 정점 선별

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

17

8

18

14

6

10

20

INF

INF

INF

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

 

O

 

 

O

O

 

 

 

 

 

M 선택됐다

 

14. 선별한 정점(M) 방문, 방문한 정점 주변에 인접한 정점들을 파악

15. 인접한 정점들중 시작점을 기준으로 해당 정점들까지의 최소 가중치 구해서 비교한뒤 빠르면 정리해놓은 최소 가중치를 수정, 느리면 그대로둠

(현재 기준점 까지의 최소가중치)+(인접한 정점까지의 가중치) < 현재 기록되어있는 최소 가중치

 

A_I = A_I(20) > A_M(13) + M_I(13) ? A_M(13) + M_I(13) : A_I(20) // 그대로

 

A_L = A_L(INF) > A_M(13) + M_L(7) ? : A_M(13) + M_L(7) : A_L(INF) // 바뀜

 

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

17

8

18

14

6

10

20

INF

INF

20

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

 

O

 

 

O

O

 

 

 

 

O

 

 

 

 

 

 

 

16. 최소 가중치들 중에 아직 방문하지 않으면서 제일 작은 가중치를 가진 정점 선별

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

17

8

18

14

6

10

20

INF

INF

20

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

 

O

 

 

O

O

 

 

 

 

O

F 선택됐다

 

17. 선별한 정점(F) 방문, 방문한 정점 주변에 인접한 정점들을 파악

18. 인접한 정점들중 시작점을 기준으로 해당 정점들까지의 최소 가중치 구해서 비교한뒤 빠르면 정리해놓은 최소 가중치를 수정, 느리면 그대로둠

(현재 기준점 까지의 최소가중치)+(인접한 정점까지의 가중치) < 현재 기록되어있는 최소 가중치

 

A_E = A_E(18) > A_F(14) + F_E(7) ? A_F(14) +F_E(7) : A_E(18) // 그대로

 

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

17

8

18

14

6

10

20

INF

INF

20

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

 

O

 

O

O

O

 

 

 

 

O

 

 

 

 

 

 

 

19. 최소 가중치들 중에 아직 방문하지 않으면서 제일 작은 가중치를 가진 정점 선별

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

17

8

18

14

6

10

20

INF

INF

20

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

 

O

 

O

O

O

 

 

 

 

O

C 선택됐다.

 

20. 선별한 정점(C) 방문, 방문한 정점 주변에 인접한 정점들을 파악

21. 인접한 정점들중 시작점을 기준으로 해당 정점들까지의 최소 가중치 구해서 비교한뒤 빠르면 정리해놓은 최소 가중치를 수정, 느리면 그대로둠

(현재 기준점 까지의 최소가중치)+(인접한 정점까지의 가중치) < 현재 기록되어있는 최소 가중치

 

A_I = A_I(20) > A_C(17) + C_I(7) ? A_C(17) + C_I(7) : A_I(20) // 그대로

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

17

8

18

14

6

10

20

INF

INF

20

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

O

O

 

O

O

O

 

 

 

 

O

 

 

 

 

 

 

 

 

 

22. 최소 가중치들 중에 아직 방문하지 않으면서 제일 작은 가중치를 가진 정점 선별

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

17

8

18

14

6

10

20

INF

INF

20

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

O

O

 

O

O

O

 

 

 

 

O

E 선택됐다.

 

 

23. 선별한 정점(E) 방문, 방문한 정점 주변에 인접한 정점들을 파악

24. 인접한 정점들중 시작점을 기준으로 해당 정점들까지의 최소 가중치 구해서 비교한뒤 빠르면 정리해놓은 최소 가중치를 수정, 느리면 그대로둠

(현재 기준점 까지의 최소가중치)+(인접한 정점까지의 가중치) < 현재 기록되어있는 최소 가중치

 

A_J = A_J(INF) > A_E(18) + E_J(11) ? A_E(18) + E_J(11)  : A_J(INF) // 바뀜

 

 

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

17

8

18

14

6

10

20

29

INF

20

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

O

O

O

O

O

O

 

 

 

 

O

 

 

 

25.최소 가중치들 중에 아직 방문하지 않으면서 제일 작은 가중치를 가진 정점 선별

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

17

8

18

14

6

10

20

29

INF

20

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

O

O

O

O

O

O

 

 

 

 

O

I L 둘다 안방문 했으면서, 그중에서 제일 작은 가중치 20 동일하게 나타내고 있다, 이럴때는 for문과 배열을 사용한다는 것을 감안하여 순차적으로 I부터 방문한다

 

 

 

26.선별한 정점(I) 방문, 방문한 정점 주변에 인접한 정점들을 파악

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

O

O

O

O

O

O

O

 

 

 

O

 

 

27.인접한 정점들중 시작점을 기준으로 해당 정점들까지의 최소 가중치 구해서 비교한뒤 빠르면 정리해놓은 최소 가중치를 수정, 느리면 그대로둠

 

※인접하면서 아직 방문하지 않은 정점이 주변에 하나도 없으므로 과정이 생략된다(반복문 안에 조건문을 만족시키지 못하고 계속 continue 되어 결국 반복문이 끝나고 다음 순서, 최소 가중치 정점 선별로 넘어가 버린다.)

 

 

 

 

 

 

 

28.최소 가중치들 중에 아직 방문하지 않으면서 제일 작은 가중치를 가진 정점 선별

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

17

8

18

14

6

10

20

29

INF

20

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

O

O

O

O

O

O

O

 

 

 

O

L 선택됐다.

 

29. 선별한 정점(L) 방문, 방문한 정점 주변에 인접한 정점들을 파악

30. 인접한 정점들중 시작점을 기준으로 해당 정점들까지의 최소 가중치 구해서 비교한뒤 빠르면 정리해놓은 최소 가중치를 수정, 느리면 그대로둠

(현재 기준점 까지의 최소가중치)+(인접한 정점까지의 가중치) < 현재 기록되어있는 최소 가중치

 

A_K = A_K(INF) > A_L(20) + L_K(7) ? A_L(20) + L_K(7)  : A_K(INF) // 바뀜

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

17

8

18

14

6

10

20

29

27

20

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

O

O

O

O

O

O

O

 

O

 

O

 

 

 

 

 

 

31. 최소 가중치들 중에 아직 방문하지 않으면서 제일 작은 가중치를 가진 정점 선별

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

17

8

18

14

6

10

20

29

27

20

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

O

O

O

O

O

O

O

 

 

O

O

K 선택됐다.

 

 

32. 선별한 정점(K) 방문, 방문한 정점 주변에 인접한 정점들을 파악

33. 인접한 정점들중 시작점을 기준으로 해당 정점들까지의 최소 가중치 구해서 비교한뒤 빠르면 정리해놓은 최소 가중치를 수정, 느리면 그대로둠

(현재 기준점 까지의 최소가중치)+(인접한 정점까지의 가중치) < 현재 기록되어있는 최소 가중치

A_J = A_J(29) > A_K(27) + K_J(9) ? A_K(27) + K_J(9)  : A_J(29) // 그대로

 

 

 

 

 

 

 

34. 최소 가중치들 중에 아직 방문하지 않으면서 제일 작은 가중치를 가진 정점 선별

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

17

8

18

14

6

10

20

29

27

20

13

 

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

O

O

O

O

O

O

O

 

O

O

O

J 선택됐다.

 

35. 선별한 정점(J) 방문, 방문한 정점 주변에 인접한 정점들을 파악

정점

A

B

C

D

E

F

G

H

I

J

K

L

M

방문

O

O

O

O

O

O

O

O

O

O

O

O

O

 

36. 인접한 정점들중 시작점을 기준으로 해당 정점들까지의 최소 가중치 구해서 비교한뒤 빠르면 정리해놓은 최소 가중치를 수정, 느리면 그대로둠

※인접하면서 아직 방문하지 않은 정점이 주변에 하나도 없으므로 과정이 생략된다(반복문 안에 조건문을 만족시키지 못하고 계속 continue 되어 결국 반복문이 끝나고 다음 순서, 최소 가중치 정점 선별로 넘어가 버린다.)

 

 

 

 

37. 해당 그래프를 기준으로 여기까지 하면 11 방문, 즉 정확히 전체정점 개(12) - 1 만큼,  아래 과정을 반복하게 된다.

 

  1. 최소 가중치들 중에 아직 방문하지 않으면서 제일 작은 가중치를 가진 정점 선별
  2. 선별한 정점 방문, 방문한 정점 주변에 인접한 정점들을 파악
  3. 인접한 정점들중 시작점을 기준으로 해당 정점들까지의 최소 가중치 구해서 비교한뒤 빠르면 정리해놓은 최소 가중치를 수정, 느리면 그대로둠
    • (현재 기준점 까지의 최소가중치)+(인접한 정점까지의 가중치) < 현재 기록되어있는 최소 가중치

 

 

 

 

알고리즘이 종료 되면, 지금까지 초기화 시켰던 최소 가중치 정리 배열에는 시작점(A) 부터 각각 정점까지 가는데 드는 최소 비용을 정리해 놓게 된다.

경로

A_A

A_B

A_C

A_D

A_E

A_F

A_G

A_H

A_I

A_J

A_K

A_L

A_M

가중치

0

9

17

8

18

14

6

10

20

29

27

20

13

예를들면 A(시작점) 에서 정점 K 까지 간다고 했을때, A -> D -> E  -> J -> K 거쳐서 수도 있겠지만

가중치 크기 비교를 하면

A -> G -> M -> L -> K( A_G + G_M + M_L + L_K )  A -> D -> E  -> J -> K(A_D + D_E + E_J + J_K) 보다 작다,

 

빠르게 있다는 뜻이고, 이렇게 다양한 정점들 속에서 나올 있는 최소비용, 최단거리들을 기록해 놓은 것이 위의 표이고, 지금까지의 과정 Dijkstra 알고리즘을 통해서 구할 있는 것이다.

 

 

지하철 노선도 앱 최단 경로 탐색

반응형

+ Recent posts