A* (A star) 알고리즘
- 주어진 출발점에서 목표점까지 가는 최단 경로를 찾아내는 그래프 알고리즘 중 하나이다.
- 적절한 휴리스틱 추정값 h(x)<!--[endif]--> 을 가지고 이 알고리즘을 사용하면 최적의 해를 얻을 수 있다.
- A* 알고리즘은 최적의 경로를 탐색하기 위해, 각각의 지점에서 다음과 같은 함수 f(n)을 이용하여
가중치를 고려한다.
f(n) = g(n) + h(n)
g(n) : 출발점으로부터 현재 위치까지의 경로 가중치
h(n) : 현재 위치로부터 목표점까지의 추정 경로 가중치
1. 동작 원리
(1) 현재 위치(시작점)에서 이동할 수 있는 지점을 열린 목록(open list)에 추가한다.
(2) 현재 위치를 다시 확인할 필요가 없는 닫힌 목록(closed list)에 추가합니다.
(3) 열린 목록에서 가장 비용이 적은 위치를 꺼내 현재 위치로 지정합니다.
(4) 목표에 도달하기 전까지 위의 과정을 반복합니다.
[ Fig . 1 ] 동작 원리 - 1 |
[ Fig. 2 ] 동작원리 - 2 |
회색 칸 - 현재 위치(시작 위치) 검은색 칸 - 닫힌 목록(이동할 수 없는 지점) 빨간색칸 - 목표 지점 회색 테두리 - 현재 위치로부터 가장 비용이 적은 지점 각 칸의 숫자 - G + H로, 좌측은 g(x), 우측은 h(x) 값이다. |
Fig. 1부터 살펴보면, 현재 위치로부터 열린 목록들의 비용을 나타내고 있다. f(x) 값을 토대로, 열린 목록 중 가장 비용이 적게 드는 곳을 선택하였다. Fig. 2을 보면, 기존 위치는 닫힌 목록이 되었고, Fig. 1에서 선택된 위치가 현재 위치가 되었다. 마찬가지로 비용이 가장 적은 위치를 탐색하였다. |
2. 함수 설명
void astar() : A* 알고리즘의 메인 부분으로, 동작원리 (4)에 해당한다.
void add_openlist() : 동작원리 (1)에 해당하는 부분으로, 목표점이 리스트에 들어오면 종료한다.
int calc_heuristic( ) : 휴리스틱을 이용하여, 각 지점들에 이동하는 비용을 계산해준다.
enqueue() : 이동 가능한 지점을 큐에 배정하는 부분, 삽입과 동시에 정렬이 이루어진다.
(= 최소값을 수월하게 찾기 위함)
3. 함수 구현
#include <stdio.h> #define MAX 10 typedef struct vertex{ typedef struct queue{ void astar( void); QUEUE *Q; /* int main( void) scanf("%d%d", &s.c, &s.r); // input a column and a row of starting point. scanf("%d%d", &e.c, &e.r); // input a column and a row of ending point. s.c --; s.r--; // have to minus number 1 because the array begins from zero. scanf("%d", &obcnt); // input the number of walls // input the coordinates of walls. visit[obc-1][obr-1] = WALL; // call the a star algorithm. print_weights(); return 0; /* // to back track, calculate the coordinate. // continuously calculate the previous coordinates. g[i][j] = 7; i = backtrack / MAX; // display the root as characters. /* for( i = 0 ; i < MAX ; i ++) printf("\n"); /* /* if( f != NULL) v.c = f->v.c; free(f); return v; return v; /* newq->next = NULL; if( f == NULL) // with insertion-sort, begin sorting process. if( key < g[f->v.c][f->v.r]) f = f->next; newq->v = v; /* // calculate h(x) value. // get g(x) value of previous vertex. // examine whether this point is located on the diagonal. return result + *gx; /* // check the vertexs that are located on the nearest points. for( j = v.r-1 ; j <= v.r+1 ; j ++) // calculate the weight about the point // if the weight that have calculated now is lower than // if this point is the same with ending point. temp.c = i; // enqueue this point. /* g[s.c][s.r] = 0; // init weight on the starting point. v = s; // make the starting point as current point. // add adjacency vertexs to the open list. while( !empty_queue()) // update current vertex // add adjacency vertexs to the open list. } |
4. 실행 결과
[ Fig. 3 ] 예제 그림
Fig. 3의 그림을 기준으로, 10 x 10 필드에 파란색이 출발점, 빨간색이 목표점 그리고 검은 색이 벽이다.
[ Fig. 4 ] 각 지점의 가중치 및 문자 표현
Fig. 3의 그림을 기준으로 알고리즘을 수행한 결과이다, 출발점, 목표점 및 벽은 가중치가 0 이고
나머지 지점은 각각 시작점으로부터의 각 최단거리 비용이다. 즉 (10, 2)에 도착하기 위한 최소한의
비용은 226이다. Fig. 4의 아래 그림은 백트래킹을 이용하여 최단거리 경로는 그림으로 표현한 것이다.
[ Fig. 5 ] 최단거리
위의 알고리즘 수행 결과를 토대로, 최단거리(초록색)을 표시하였다.
'프로그래밍 언어들 > 알고리즘' 카테고리의 다른 글
최소신장트리(Minimum Spanning Trees) 크루스칼(Kruskal) 알고리즘 (2) | 2016.10.19 |
---|---|
벨먼-포드 알고리즘(Bellman-Ford algorithm) (1) | 2016.10.18 |
다익스트라(dijkstra) 알고리즘 (0) | 2016.10.14 |
너비우선탐색(BFS : Breadth First Search) (0) | 2016.10.13 |
깊이우선탐색(DFS : Depth First Search) (0) | 2016.10.13 |