내가 만든 길찾기에서는 그냥 피타고라스 정리로 휴리스틱을 사용했는데 검색해보니 다양한 방법들이 있다는 것을 알게 되었다.
A* 의 성능에는 휴리스틱이 많은 영향을 끼치므로 좋은 휴리스틱을 사용해야한다.
휴리스틱 정확도가 낮을 수록 최단거리를 얻을 수 있지만 A*의 전체 속도가 느려지고,
휴리스틱 정확도가 높을 수록 A*의 전체 속도가 빨라지지만 최단거리를 포기해야한다. (출처)
따라서 속도와 정확도의 균형이 중요하다.
두 점 좌표 a(x1, y1, z1), b(x2, y2, z2)이고
a와 b의 휴리스틱 거리값이 distance라고 친다.
1. 맨하탄 방식
distance= fabs(x2 - x1) + fabs(y2 - y1)
목표까지 도달하는 가로와 세로의 길이만을 고려한다. 장애물은 고려하지 않는다.
2. 피타고라스 정리
distance = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1)* (y2 - y1))
이차원 공간에서 두 점 사이의 대각선 거리를 나타낸다.
3. 유클리디안 거리 공식
피타고라스 정리의 다차원 버전이다.
맨하탄 방식보다 더 정확하지만, 더 넓은 영역을 탐색하기 위해 속도가 비교적 느리다.
distance = 1 / (1 + sqrt(pow((x2 - x1), 2.0f) + pow((y2 - y1), 2.0f) + pow(y1 - y2, 2.0f)));
루트를 씌워서 나온 값에 1을 더하고 역수를 취하면 0~1 사이의 값이 나온다.
거리가 가까울 수록 1이 되고 멀 수록 0이 된다.
+ 가중치 A* (Weighted A*)
휴리스틱 함수에 가중치(ε)를 곱하는 방식이다. 한 블로그에서 알게 된 방식이다.
일반 A* 공식 : F = G + H
가중치 A* 공식 : F = G + εH
가중치를 어떻게 산정하는지 찾아봤는데 딱히 정해진 공식은 없는 것 같다.
이 그림(출처)을 보면 가중치가 1에 가까울수록 최단 거리를 구할 수 있지만 더 많은 노드를 탐색하므로 시간이 더 걸릴 것이라고 추측할 수 있다. 따라서 빠르게 찾는 것이 더 중요한 경우 가중치를 높이고 느리더라도 최단거리를 찾는 것이 더 중요한 경우 가중치를 낮추면 된다.
휴리스틱 함수 중 어떤 방식을 써야할까?
이 글에 따르면 이동방향이 4방향이나 6방향인 경우 맨하탄 방식, 8방향인 경우 피타고라스 방식, 모든 방향이 가능한 경우 유클리디안 방식이 좋다고 한다.
'C++' 카테고리의 다른 글
DFS 구현 (재귀, 스택) (0) | 2020.02.16 |
---|---|
A* 알고리즘 설명 (0) | 2020.02.16 |
NULL과 nullptr의 차이 (0) | 2020.02.04 |
namespace 사용 이유 (0) | 2020.01.26 |
call-by-value와 call-by-reference의 차이 (0) | 2020.01.26 |