원문보러가기: http://www.policyalmanac.org/games/aStarTutorial.htm
초보자를 위한 AStar 길찾기 알고리즘
초보자를 위한 AStar 길찾기 알고리즘(사실은 번역 ㅋㅋㅋ)
원문 http://www.gamedev.net/reference/programming/features/astar 2004. 4. 22 영어가 딸려 번역하는데 무지 많은 시간이 소요되었으며, 영어식 표현으로 쓰기가 영 어색한 것은 한국식 표현으로 바꾸어 쓰기도 하였습니다. 영어실력이 쫌 되시는분은 좀더 자연스러운 번역으로 다시 올려주셔도 좋을 듯 합니다. 아참! 쓰다보니 반말 존댓말 마구 썩어 놓았는데 너그러이 용서하시길~ Cafe: http://cafe.naver.com/rosuslab.cafe Email: debugman@hitel.net ------------------------------------------------------------------- 이 알고리즘은 이미 스페인어와 프랑스어로 변역되었으며, 또 다른 언어로의 번역도 환영합니다.( 내 것도 링크해 달라고 할까 ~ㅎㅎ ) 당신이 쉽게 A*알고리즘을 이해할 때, 이 A*알고리즘은 초보자에게는 복잡하게 느껴질수도 있습니다. A*알고리즘을 해석한 논설들이 웹상에 많이 존재합니다. 그러나 그 글들의 대부분은 이미 기본적인 것을 이해한 사람들을 위해 쓰여진 글들이지만. 그와 달리 이 글은 진정 초보자들을 위한 것입니다. 이 논설은 A*길찾기 알고리즘의 주제를 완벽히 보여주도록 노력하지는 않습니다. 그보다는 당신이 앞으로 관련된 다른 좀더 구체적인 글들을 읽고 이해하는데 필요한 A*길찾기 알고리즘의 원리와 기본적인 것들을 설명하고 있습니다. 나중에 여러분들이 읽을수 있도록 최고의 몇몇 웹사이트 링크를 마지막 부분에 제공합니다. 마지막으로, 이 논설은 어느한쪽으로 특유화된 프로그램이 아닙니다. 나는 이 논설의 마지막 부분에 C++과 Blitz Basic 두가지 버전의 샘플프로그램 패키지의 링크를 넣어 놓았지만 당신은 어떤 컴퓨터 언어로든 A*알고리즘을 적용하는 것이 가능할 것입니다. 샘플프로그램에는 당신이 A*가 동작하는 것을 볼수있도록 실행파일도 포함시켜 놓았습니다. 자~ 처음부터 시작해 보자... 우리스스로 헤처나가 보자 ~Let's Go(^^b) 도입: 범위 찾기(The Search Area) 자~ 가정해 보자 누군가가 A지점에서 B지점으로 가기를 원한다. 그리고 벽이 이 두 지점을 분리시켜놓고 있다. 이것에 대한 그림이 아래에 있다. 녹색은 출발지점A, 빨간 것은 도착지점B, 그리고 파란색으로 채워진 사각형은 양쪽사이에 있는 벽이다.
먼저 알수 있는 것은 우리의 검색지역이 사각형 격자들(Grid)로 나누어져 있다는 것이다. 우리는 이 단순화된 검색지역 사용한다. 우리가 첫 단계로 할 것은 길 찾기이다(당근이쥐!). (격자들로 지역을 단순화시킨) 이런 특별한 방법은 우리의 검색지역을 단순한 2차원배열로 만들어준다. 각각의 아이템(시작지점,도착지점,벽,길 등등)은 사각형 격자위에 하나의 2차원배열로 묘사된다. 그리고 이것은 ‘갈수 있는곳’, ‘갈수없는곳‘ 이런식으로 상태가 기록된다. 우리가 A에서 B로 갈 수 있는 길은 어떠한 사각형들의 모양으로 나타난다. 사각형의 중앙에서 다음 사각형의 중앙으로의 이동을 목표에 도착할때까지 하면서 길이 찾아진다. 이 중심점들을 노드 라고 부른다. 당신이 다른곳에서 길찾기에 대해 들을때, 사람들이 노드에 대해 토론하는 것을 종종 볼수 있을것이다(그런사람 없는데ㅡㅡ;). 왜 그것들을 사각형으로 사용하지 않지?(사각형을 사용하지 않는 사람들도 있나보다.) 왜냐하면 사각형보다 좀더 다른 것으로 검색지역을 나누는 것이 가능하기 때문이지. 그들은 직사각형, 육각형 또는 어떤모양이든 할수 있어~, 진짜루-. 그리고 노드는 그 형태 안에서 중심, 외각선사이 또는 다른 어디이든 위치할수 있어. 우리는 이 방식을 사용할거야 왜냐면 이것이 가장 단순한 방식이니까!(사각형을 쓰는것이? 아니면 A*길찾기 방식이? 이 방식이란 뭘 말하는것일까^^) 다음의 순서들을 실행 하므로써 우리는 길 찾기를 한다. 1. 지점A로부터 충분히 검토된 사각형을 열린목록(open list)에 추가한다. 열린목록은 쇼핑목록과 비슷하다. 지금은 목록상에 아이템이 하나이지만 나중에 좀더 갖게 될 것이다. 이것은 당신이 갖기를 원하는 길을 따라 저장 할 수도 있다. 그러나 그럴 수는 없다. 기본적으로 이사각형들의 목록은 검사가 필요하기 때문이다. 주) krkim 다음으로, 우리는 열린목록에 있는 인접한 사각형중에 하나를 선택하고 앞에서 했던 처리를 아래에 설명된 방법으로 반복한다. 좀더 많이 할 수도 있고 덜 할 수도 있다. 그런데 어떤 사각형을 선택해야 할까? 그것은 바로 가장 작은 F비용을 가진 것을 선택한다. (F비용이 무엇 일까요?? ^^ 아래를 보면 알게 된다구요.~) 길 기록(Path Scoring) 길을 찾아내야 할 때 사용할 사각형을 선택하는 방법은 바로 다음 방정식이다. F = G + H G, H 요것들이 무엇이냐 하 믄~ - G = 출발점 A로부터 얻어진 새로운 사각형까지의 이동비용(시작지점으로 부터 온거리)이다. 길을 찾아가면서 생성되게 된다. - H = 얻어진 사각형으로부터 최종목적지점 B까지의 예상이동비용(목표지점까지 갈거리)이다. 이것은 매번 조회될때마다 발견된다. 이것은 좀 당황스러울수 있다. 왜냐면 예상이동비용라고 불리듯이 이값은 추측이기 때문이다. 우리는 완전한 길을 찾을때까지 정확한 거리를 알수 없다. 왜냐하면 모든성격의 것들(물,벽,기타등등 갈수없는사각형)이 길위에 있기 때문이다. 당신은 H를 계산하는 한가지 방법을 연습을 통해 알게 될것이다. 그리고 H를 계산하는 방법은 웹상에 다른 많은 방법이 존재한다. 우리의 길은 열린목록과 F비용이 작은 사각형을 선택하는것의 반복을 통해서 얻어진다. 이 반복처리는 앞으로 이 논술 안에서 좀더 자세히 설명 될 것이다. 일단 우리가 어떻게 이 방정식을 계산하는지 세심히 보자. 위에 설명된 것처럼, G는 출발점으로부터 길을 만들기 위해 얻게 되는 사각형으로 이동하는데 드는 이동비용이다. 이 예제에서 우리는 세로 또는 가로로 이동하는데 각각 10의 비용을 할당 할 것이다 그리고 대각선이동에 대해서는 14의비용을 할당 할 것이다. 우리는 이 숫자들을 사용할것이다. 왜냐하면 대각선으로 이동하는 비용은 2의 루트이고 또는 대충 가로또는 세로로 이동하는거의 1.414배이기 때문이다.(정사각형 대각선 길이 = 빗변길이 * 루트2) 단순하게 하기위해 우리는 10과 14를 사용한다. 비율은 거의 맞다. 그러므로써 우리는 루트 계산과 10진법을 피한다. 이것은 우리가 벙어리이거나 수학을 싫어하기 때문이 아니다. 그와 같은 숫자들을 사용하는 것은 컴퓨터에서도 역시 매우 빠르기 때문이다. 그것들과 같이 단순화 시킨 숫자들을 사용하지 않는다면 길찾기가 매우 느려진다는 것을 당신은 금방 알게 될 것이다. 우리는 얻어지는 사각형의 일정한 길을 따라 G비용을 계산하기 때문에, 사각형의 G비용을 알아내는 방법은 그 부모로부터 G비용을 가져와서 부모로부터 직각으로 움직였냐 대각선으로 움직였냐에 따라서 10또는 14를 추가해 주는것이다. 이 방법이 좀더 명확하게 되도록 하기위해서 이 예제상에서 좀더 멀리까지 해볼 필요가 있다. 그래서 우리는 시작점으로부터 떨어져 있는 하나 이상의 사각형을 얻는다. H는 길들의 변화 안에서 어림잡아 예측될 수 있다. 우리가 사용하는 이 방법을 맨하탄방식(Manhattan method)이라고 부른다. 당신은 현재사각형에서 목표사각형에 도달하기 까지의 대각선이동을 제외한 가로 또는 세로로 이동한 총숫자를 계산할수 있다. 그리고 거기에 10을 곱한다. 이것이 바로 맨하탄방식인데 이것은 도시에 한쪽에서 다른 한쪽까지의 블록을 계산하는것과 같은 방식이기 때문이다. 여기서 당신은 대각선으로 블록을 가로질러 자를수는 없다. 중요하게도, H비용을 계산할 때 우리는 어떤 끼여드는 방해물도 무시한다. H비용은 단지 남은거리에 대한 어림잡은 추측일 뿐이다. 진짜 거리가 아니다. 또한 발견적방식이라고 불리는 이유이기도하다. 좀더 알기를 원하는가? 당신은 발견적방식상의 방정식들과 추가적인 사항들을 여기(http://www.policyalmanac.org/games/heuristics.htm)에서 발견할수 있을 것이다. G와 H를 더하므로써 F 가 계산된다.우리의 검색의 첫단계의 결과를 아래 그림에서 볼수있다. F,G,H 비용이 각각의 사각형에 표시되어 있다. 시작사각형에 오른쪽에 있는 사각형안에 표시된것처럼, F는 좌상단에, G는 좌하단에, 그리고 H는 우하단에 표시되어 있다. 그럼, 저 몇몇 사각형들을 살펴보자. 글자와 같이 있는 사각형을 보면, G비용이 10이다. 이것은 시작 사각형으로부터 수평방향으로 위치한 사각형이기 때문이다. 즉, 시작사각형으로부터 곧장 위, 아래, 왼쪽, 오른쪽에 있는 모든사각형들은 모두 똑같이 G비용이 10이다. 대각선으로 위치한 사각형들은 모두 14의 G비용을 갖는다. H비용은 맨하탄 방식으로 빨간 목적지 사각형까지의 거리를 추측하여 계산된다. 가로, 세로 방향으로만 움직이고 길위에 있는 장애물들은 그냥 무시된다. 이 방식대로 한번 해보자, 시작사각형에 오른쪽에 있는 사각형은 목표사각형으로부터 3개의 사각형만큼의 거리에 있으므로 H비용은 30이다. 이사각형에 위에 있는 사각형은 4개의 사각형만큼 떨어져 있으므로 H비용이 40이다(가로,세로 로만 움직인다는 것을 명심해라). 이제 당신도 다른 사각형들의 H비용을 어떻게 계산해야 할지 느낌이 올것이다. 이제 F비용은 단순히 H 와 G 값을 더하면 되는것이다. 계속 찾기(Continuing the Search) 계속 찾기를 해 나가기위해서 우리는 단순히 열린목록에 있는 사각형들 중에서 가장 작은 F비용을 가지고 있는 사각형을 선택하고 그 선택된 사각형으로 다음의 과정을 하면 된다.
4. 이것을 열림목록에서 빼고 닫힌목록(검사를 끝낸)에 추가한다. 5. 인접한 모든 사각형을 검사해서 닫힌목록에 있거나 갈수없는것(벽,물,그밖에 장애물)들을 제외하고 나머지중에서 열린목록에 들어가 있지 않은것들을 열린목록에 추가한다. 선택되었던 사각형을 새로운 사각형들의 부모로 만든다.(선택되었던 사각형이란 4.에서 단힌목록에 추가된 그 사각형을 말한다. 새로운 사각형이란 5.에서 열린목록에 새롭게 추가된 사각형을 말한다.) 6. 만약 인접한 사각형중에 이미 열린목록에 있는 사각형이 있다면 이사각형으로 가는길이 더 좋은 길인지 확인해 봐라. 다시 말하면, 우리가 현재 선택된 사각형을 경유해 가는 G비용이 기존의 G비용보다 더 작은지를 검사해 봐라. 만약 아니라면 아무것도 할 필요가 없다. 그러나 새로운 길이 G비용이 더 작다면 인접사각형들의 부모를 현재 사각형으로 바꿔라(위쪽 그림에서 보면, 선택된 사각형으로 향하는 포인터들의 방향을 바꾸는 것을 말한다.). 그리고 그 인접 사각형의 F와 G를 다시 계산해라. 이것이 좀 복잡하게 느껴진다면, 아래 그림을 보아라 .
만약, 더 적은비용이라면 그 인접사각형의 F와 G를 갱신하고 부모사각형을 현재 사각형으로 저장한다. 제일 먼저 할 것은, 이 사각형을 열린목록에서 빼고 닫힌목록에 넣는다. (이것이 바로 지금 저 사각형이 파란색 외관선으로 강조된 이유이다). 그리고 우리는 인접한 사각형들을 검사한다. 오른쪽에 있는 사각형은 벽이다. 그래서 이것들은 무시한다. 왼쪽에 있는 것은 시작사각형이고 이것은 닫힌목록에 있다. 그래서 이것역시 무시한다. 이미 열린목록에 나머지 4개의 사각형들이 있으므로 이를 비교해야 한다.이미 열린목록에 있는 이들중에 현재 사각형을 경유하여 가는 G비용이 더 좋은지를 검사해야한다. 우상단의 사각형을 보자. 이것의 G비용은 14이다. 만약 우리가 현재 선택된 사각형을 거쳐서 그곳으로 이동한다고 하면 G비용은 20과 같을것이다(현재사각형이 G비용이 10이고 이것에서 수직으로 위쪽으로 한번 이동하였으므로 10을 더한다.). G비용 20은 그것이 원래 갖고 있던 14 보다 크다. 그래서 이것은 좋은 길이 아니다. 이것은 그림을 보다시피, 단순히 시작사각형에서 대각선으로 1번 움직이는 것이 가로로 한번 세로로 한번 움직이는거 보다 더 직접적으로 가깝다는 것을 알수있다. 우리가 열린목록상에 이미 있는 4개의 인접한 사각형에 대한 처리를 할때, 현재의 사각형으로는 더 좋은 G 비용이 없으므로 더 이상 길을 개선할 수 없다는 것을 알게 된다. 그래서 우리는 아무것도 변경하지 않았고 이제는 인접한 주변 사각형들에 주목하자. 이제 우리는 이것을 가지고 처리 할 것이고, 다음 사각형으로 이동할 준비를 할 것이다. 그래서 우리는 열린목록으로 돌아가서 다음 이동할 사각형을 찾기 위한 처리를 한다. 그래서, 우리는 그냥 단지 아래쪽에 있는 것을 선택하자, 그리고 다음 그림에 보여지는 시작사각형의 오른편을 보자 이제, 우리는 좌표 (2,3) 에 위치한 현재사각형(F=54,G=14,H=40)의 인접한 사각형들을 검사할 때 바로 오른쪽에 사각형이 벽이라는 것을 발견하게 된다. 그래서 우리는 이것을 무시한다. 그 바로위도 똑같이 벽이기 때문에 이것도 역시 무시한다. 그리고 우리는 벽 바로 아래 사각형(3,4)도 무시한다. 왜그럴까? 왜냐하면 당신은 벽의 모서리 부분을 자르지 않고는 그 사각형으로 바로 갈수가 없기 때문이다.(뽀쪽한게 막구있잖아요~). 당신은 일단 밑으로 내려가서 그다음 그사각형을 거쳐서 지나간다. 이 처리에서는 이렇게 코너를 돌아서 이동한다. (노트: 코너를 자르는 규칙은 당신의 선택이다. 당신의 노드를 어떻게 위치시키느냐에 따라서 사용된다.) 이렇게 5개의 사각형이 계산에서 빠진다. 현재사각형 아래에 있는 2개의 사각형은 열린목록에 없는것이다. 그래서 우리는 이것들을 그냥 추가만 해주고 현재 사각형을 이것들의 부모로 저장한다. 다른 3개의 사각형중 2개는 이미 닫힌목록(시작사각형과 현재사각형위에있는 사각형, 둘다 파란색 외관선안에 있다)상에 있다. 그래서 우리는 이것들을 무시한다. 그리고 바로 왼쪽에 있는 마지막 사각형은 열린목록에 이미 추가된 것이므로 검사를 해야한다.즉,현재사각형을 통해서 가는 G비용이 기존의 G비용보다 적은지 검사를 해보자. G가 30이므로 아니군~, 그래서 현재 사각형에 대한 처리는 모두 끝났고 다시 열린목록으로 돌아가 다음으로 이동할 사각형을 검사 해보자 우리는 목표사각형을 열린목록에 추가 할때까지 이 처리를 계속 반복한다. 이것에 대해 정리된 그림을 아래에서 볼수 있다. 시작사각형으로부터 2개의 사각형만큼 밑에 있는 사각형의 부모사각형이 이전 그림에서 변경되었다는 것을 주목하라. 전에 이것은 G비용이 28이었고 오른쪽위에 사각형을 가리키고 있었다. 지금은 G비용은 20이고 위쪽 사각형을 가리키고 있다. 이 일은 우리가 길찾기를 처리해 나가면서 어디선가에서 일어난 것이다. 어딘가에서 G비용을 검사했고 여기서 더 비용이 적게드는 길을 찾아냈다 그러므로써 부모가 바뀌것이고 G, F비용이 다시 계산되어진것이다. 이변화가 일어나는 동안에 예제에서 아주 중요하다고 보이는 것은 없는 것 같다. 가능성이 많은 장소들에서 이 검사는 목표지점으로 가는 가장 좋은 길을 찾아가면서 모든 것들을 다르게 만들것이다.(모든것들이란~ 더 빨리 갈 수 있는 곳을 말하는듯~-_- 그러니까 좀더 좋은 길은 G,F 값이 전하고 다른게 바뀐다. 이런 뜻인 것 같다.) 그래 그러면 이제 어떻게 최종적인 진짜 길을 찾아내지? 단순히, 단지 빨간 목표지점에서 시작해서 화살표를 따라서 부모사각형으로 한걸음씩 거슬러 올라가면 된다. 이렇게하면 결국 시작사각형까지 되돌아 가게된다. 그리고 그것이 당신의 최종적인 길이다. 이것은 다음의 그림에서 볼수있다. 시작지점 A에서 목표지점 B까지 이동하는 것은 단순히 길을 따라있는 각각의 사각형의 중심(노드)에서 다음사각형의 중심으로 이동하면 된다. 당신이 목표지점에 도달할때까지~ 쉽지~ㅋ 좋다. 지금시점에서 이제 당신은 설명을 통해서 했던 것 들은 까먹었을 것이다. 차례차례 이 A* 방식을 여기에서 정리해보자. 1. 시작사각형을 열린목록에서 넣는다. 2. 다음의 과정들을 반복한다. a) 열린목록에서 가장 낮은 F 비용을 찾는다. 그리고 우리는 이것을 현재사각형으로 선택한다. b) 이것을 닫힌목록으로 바꾼다. c) 현재 사각형에 인접한 8 개의 사각형에 대해? ● 만약 인접한사각형이 갈수없는 것 이거나 그것이 닫힌목록상에 있다면 이것은 무시한다. 그렇지 않은것은 다음을 계속한다. ● 만약이것이 열린목록에 있지 않다면, 이것을 열린목록에 추가한다. 이사각형의 부모를 현재 사각형으로 만든다. 사각형의 F,G,H 비용을 기록한다. ● 만약 이것이 이미 열린목록에 있다면, 사각형 G비용을 이용하여 이사각형이 더 나은가 알아본다. 그것의 G비용이 더 작으면 그것이 더 나은 길이라는 것을 의미한다. 만약 그렇다면, 부모 사각형을 그 (G비용이 더 작은)사각형으로 바꾸어라, 그리고 그 사각형의 G,F비용을 다시 계산해라. 만약 당신이 당신의 열린목록을 F비용으로 정렬하고 있다면 바뀐것에 따라서 열린목록을 다시 정렬해야한다. d) 그만할 때 ● 길을 찾다는 중 목표사각형을 열린목록에 추가하였을때, ● 열린목록이 비어있게 될 경우 이때는 목표사각형을 찾는데 실패한것인데 이 경우 길이 없는경우다. 3. 길 저장하기~. 목표사각형으로부터 각각의 사각의 부모쪽을 향하여 시작사각형에 도착할때까지 거슬러 올라간다. 이것이 당신의 길이다.~
♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡ 일단, 여기까지 A*알고리즘에 대한 전체적인 설명은 끝났습니다. 허접한 번역 끝까지 읽어 주셔서 감사합니다. |
http://hackish.tistory.com/21
http://cafe.naver.com/rosuslab.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=10
'SNS | SNG' 카테고리의 다른 글
페이스북서 한국 소셜게임 첫 돌풍…"사용자 요구대로 만들었더니 성공" (0) | 2011.04.25 |
---|---|
전자신문 게임빌 `트레인시티`, 페이스북서 월 이용자수 100만명 돌파 (0) | 2011.04.25 |
마로의 꿈 8방향 길찾기 알고리즘 확장하기 (1) | 2011.04.17 |
직선의 방정식을 이용한 isometric 타일 마름모꼴 영역에서 마우스 좌표 확인 (1) | 2011.04.08 |
물리로 배우는 플래시 (0) | 2011.04.07 |