1.0.0

A* 알고리즘

최단 경로를 찾을 때 가장 많이 사용하는 알고리즘으로 다익스트라 알고리즘을 확장시킨 알고리즘이다. A* 알고리즘은 출발점을 제외한 각각의 점에 대해 도착점까지의 예상 거리 (예를 들어, 지도상의 좌표로 계산된 직선 거리)를 추가하여 고려한다. 즉, A* 알고리즘은 각 지점마다 출발점으로부터의 거리뿐만 아니라 도착점까지의 예상 거리의 합까지 고려하여 다익스트라 알고리즘을 수행한다. 도착점과 반대 방향에 있는 점이 출발점에 가깝다 하더라도, A* 알고리즘은 도착점 방향에 있는 점들의 최단 경로를 우선적으로 계산해 출발점과 도착점간의 최단 경로를 다익스트라 알고리즘보다 빨리 찾는다. A* 알고리즘은 **휴리스틱 함수(heuristic function)**를 이용한다.

탐색과정

![]({{ "/assets/images/algo/astar1.png" | absolute_url }})

녹색 출발지점(A), 빨간색 도착지점(B), 파란색 벽일때, 검색지역(흰색)이 사각형 Grid형태로 나누어져있다. 이 탐색범위를 단순히 2차원 배열로 만들어준다.

갈 수 있는길(흰색), 갈 수 없는길(파란색, 장애물)로 상태가 기록해두어 갈 수 있는 길만 탐색한다.

![]({{ "/assets/images/algo/astar2.png" | absolute_url }})

  • 출발노드(A)에 붙어있고 지나갈 수 있는 모든 길(벽, 범위를 벗어난 곳)을 open list에 추가한다. 추가된 노드들은 출발노드(A)를 부모 노드라 기록한다.(Backtracking)

  • 출발노드를 open list에서 빼고, 방문했다는 것을 표시하기 위해서 closed list에 추가한다.

open list에 저장된 인접노드(화살표)중 어떤 노드를 선택해야할까? 가장 적은 F비용을 가진 것을 선택한다.

A* 알고리즘은 출발 노드로부터 목표 노드까지의 최적 경로를 탐색하기 위한 것이다. 이를 위해서는 각각의 노드에 대한 평가 함수를 정의해야 한다. 이를 위한 평가 함수 f(n)은 다음과 같다.

f(n) = g(n) + h(n)

  • g(n) : 출발 노드로부터 현재 노드 까지의 경로 가중치

    • g(n) 은 부모노드(이전노드)로 부터 경로 가중치를 얻어와 더해준다.

  • h(n) : 현재 노드로부터 목표 노드까지의 추정 경로 가중치( 장애물에 대해서 고려하지 않고 계산한다.)

    • h(n) 은 노드의 위치의 변화에 따라서 예측할 수 있다. h(n)이 휴리스틱 함수이며, 여기서는 맨하탄 방식(manhattan method)를 사용할 것이다. : 대각선 이동을 제외한 가로, 세로 이동한 총 숫자 * 10

보통 가로, 세로 10, 대각선은 14의 경로 가중치를 할당한다.

![]({{ "/assets/images/algo/astar3.png" | absolute_url }})

  1. 출발노드 open list(우선순위 큐)에 넣는다.

  2. 출발노드 open list에서 pop(), closed list에 추가

  3. 출발노드를 기준으로 주변노드를 탐색해 F가중치와 부모노드 구함

  4. 계산된 주변 노드 open list에 push()

![]({{ "/assets/images/algo/astar4.png" | absolute_url }})

  1. open list에서 F값이 가장 작은 노드 pop()

  2. 주변 탐색 가능한 노드 찾기

    • 출발노드는 closed list에 존재하므로 무시

    • 장애물도 무시

  3. F가 54인 두개 노드는 open list에 있으므로 현재 노드를 거쳐가는 경로 가중치와 비교

    • F=54의 G=14가 F=40을 거쳐가는 G=20보다 작으므로 값을 변경하지 않음

  4. F=40 closed list push

![]({{ "/assets/images/algo/astar5.png" | absolute_url }})

  1. open list에서 F값이 가장 작은 노드 pop() : F=54

  2. 주변 탐색 가능한 노드 찾기

    • closed list에 존재하는 노드 무시

    • 장애물도 무시

  3. F가중치를 비교해 기전의 값이 더 작으면 갱신하지 않음

  4. open list에 없는 노드 F 가중치 계산후 push()

위와 같은 과정을 반복한다.

![]({{ "/assets/images/algo/astar6.png" | absolute_url }})

![]({{ "/assets/images/algo/astar7.png" | absolute_url }})

![]({{ "/assets/images/algo/astar8.png" | absolute_url }})

![]({{ "/assets/images/algo/astar9.png" | absolute_url }})

![]({{ "/assets/images/algo/astar10.png" | absolute_url }})

목표노드에서 부터 부모노드를 따라서 되돌아가면 최단경로가 구해지는 것을 볼 수 있다.

C언어 구현

heuristic

open list

astar

backtracking

단점

맵의 크기가 커지면 open list나 close list의 목록에 수백에서 수천 개의 노드가 들어갈 수 있기 때문에, 메모리를 많이 사용하게 된다. 또한 시작노드에서 목표노드까지 경로가 존재하지 않는다면, A*는 시작 위치에서 도달 할 수 있는 모든 위치를 검색해 비효율적이다.

A* 알고리즘의 가장 근본적인 약점은 열린 목록과 닫힌 목록을 관리하는 비용이다. 이를 극복하기 위하여 열린 목록과 닫힌 목록을 사용하지 않는 IDA* 알고리즘이 제안되었다. 그러나 IDA* 알고리즘은 깊이 우선 검색을 사용하여 메모리 공간을 적게 사용하는 대신 노드들을 재 방문해야하는 단점이 있다.

참고사이트

  • 위키피디아

Last updated