그리드에서 A *로 자연스러운 경로를 만드는 방법은 무엇입니까?


13

나는 이것을 읽고있다 : http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html

그러나 내가 이해할 수없는 몇 가지가 있습니다. 예를 들어 기사는 대각선 이동으로 길 찾기에 이와 같은 것을 사용한다고 말합니다.

function heuristic(node) =
    dx = abs(node.x - goal.x)
    dy = abs(node.y - goal.y)
    return D * max(dx, dy)

나는 기사 에서처럼 자연스럽게 보이는 경로를 얻기 위해 D를 설정하는 방법을 모른다 .D는 그것이 말하는 것처럼 인접한 사각형 사이에서 가장 낮은 비용으로 설정했으며 휴리스틱에 대한 것들이 무엇을 의미하는지 모르겠다. 4 * D이어야합니다. 아무것도 변경하지 않는 것 같습니다.

이것은 휴리스틱 함수 및 이동 함수입니다.

def heuristic(self, node, goal):
    D = 5
    dx = abs(node.x - goal.x)
    dy = abs(node.y - goal.y)
    return D * max(dx, dy)

def move_cost(self, current, node):
   cross = abs(current.x - node.x) == 1 and abs(current.y - node.y) == 1
   return 7 if cross else 5

결과:

여기에 이미지 설명을 입력하십시오

원활한 항해 경로 :

여기에 이미지 설명을 입력하십시오

내 코드의 나머지 부분 : http://pastebin.com/TL2cEkeX


최신 정보

이것이 지금까지 찾은 최고의 솔루션입니다.

def heuristic(node, start, goal):
    dx1 = node.x - goal.x
    dy1 = node.y - goal.y
    dx2 = start.x - goal.x
    dy2 = start.y - goal.y
    cross = abs(dx1*dy2 - dx2*dy1)

    dx3 = abs(dx1)
    dy3 = abs(dy1)

    return 5 + (cross*0.01) * (dx3+dy3) + (sqrt(2)-2) * min(dx3, dy3)

def move_cost(current, node):
    cross = abs(current.x - node.x) == 1 and abs(current.y - node.y) == 1
    return 7 if cross else 5

그것은 두 번째 그림에서 원하는 경로를 생성하지만 장애물을 잘 처리하지 못하고 (벽을 기어 다니는 경향이 있음) 때로는 더 먼 거리에서 최적의 경로를 생성하지 못합니다.

개선을 위해 적용 할 수있는 조정 및 최적화에는 어떤 것이 있습니까?


2
직교 거리를 휴리스틱으로 사용하면 어떻게됩니까?
Jimmy

2
여기는 단지 아이디어 일뿐입니다. 모든 단계 에이전트가 동일한 방향으로 이동할 때마다 한 타일에서 다른 타일로 이동하는 비용이 증가합니다.
Ali1S232

@ Jimim sqrt (pow (goal.x-node.x, 2) + pow (goal.y-node.y, 2)) 시도하고 작은 예제 경로에서는 실제로 내 질문의 그림과 정확히 동일합니다. .
익명의 기업

답변:


10

A *는 그래프에서 가장 짧은 경로를 제공합니다. 그리드를 그래프로 사용하는 경우 여러 개의 최단 경로 가 종종 있습니다. 첫 번째 그림에서, 그것은 이다 최단 경로 중 하나. 모든 축 방향 이동을 먼저하고 나중에 모든 대각선 이동을합니다. 그러나 그것은 모든 대각선을 먼저 놓거나 축과 대각선 움직임을 혼합 한 것과 같은 길이의 경로입니다. 이것들은 모두 똑같이 짧으며, 코드 작성 방법과 그래프 표현 방법에 따라 A * 선택 중 하나가 달라집니다.

나는 당신이 원하는 것이 다음 중 하나라고 생각합니다.

  1. 그리드에서 이동해야하지만 축과 대각선 단계를 혼합하여 모양이 더 좋아 보입니다. 한 가지 방법은 다른 짧은 경로 중 하나를 선택하는 것입니다. 휴리스틱 페이지를 계속 읽고 "타이 브레이킹"을 찾으십시오. 다른 방법은 이웃을 평가할 때 항상 먼저 다른 것을 선택하지 않도록 먼저 어느 것을 먼저 평가할지 선택하는 것입니다. 그리드에서 이동하려면 유클리드 / 카테 시안 거리를 사용 하지 않는 것이 좋습니다. A * 실행 속도가 느려지는 불일치입니다.
  2. 그리드에서 이동할 필요가 없으며 직선으로 이동하려고합니다. 한 가지 방법은 "스트링 풀링"을 사용하여 경로를 똑 바르게하는 것입니다. 경로가 회전하는 지점을 찾고 해당 지점 사이에 직선을 그립니다. 또 다른 접근법은 이것을 기본 그래프 자체에 적용하는 것입니다. 그리드에서 길 찾기 대신 맵의 주요 지점을 길 찾기 한 다음 해당 주요 지점 사이에서 직선을 따라 이동합니다. 여기서 예를 볼 수 있습니다 . 또 다른 접근법은 Theta * 알고리즘 입니다.

좋은 대답입니다. 새로운 정보로 내 질문을 업데이트했습니다. 답을 조금 지정할 수 있기를 바랍니다.
익명 실체

장애물에 대해서는 조금 기대됩니다. 휴리스틱 페이지에는“장애물이 적다”라는 제목의 다이어그램이 있습니다. 타이 브레이킹 접근법은 장애물 주위에 큰 도움이되지 않습니다. Theta *와 같은 다른 접근 방식 중 하나가 원하는 것일 수 있습니다.
amitp

2

A * 알고리즘을 사용하면 경로 가장자리에 다른 비용을 할당 할 수 있습니다. 상황에 따라 비용을 할당 할 수도 있습니다. 이것은 A * 경로를 원하는 모양으로 만드는 주요 도구입니다.

긴 대각선을 사용하지 않으려면 불이익을 줄 수 있습니다. 경로가 같은 방향으로 갈 때마다 약간의 비용이 추가됩니다. 이 작업을 수행하면 알고리즘은 전체 경로에 걸쳐 대각선 단계를 가능한 한 고르게 분배하려고 시도합니다. 이 추가 비용이 추가 에지를 가져 오는 비용 이상이되지 않도록하십시오. 그렇지 않으면 알고리즘이 직선을 피하기 위해 불필요한 불필요한 우회를 시작합니다.

좋은 공식은 다음과 같습니다.

cost = normal_cost * (1.1 - 0.1 / num_of_steps_in_the_same_direction)

이를 위해서는 경로 비용이 정수가 아닌 부동 소수점 값으로 추적되어야합니다.


1

A * 적응

Philipp이 말했듯이 방향이 오랫동안 바뀌지 않으면 비용을 추가해야합니다. 그러나 Philipp의 기능은 추가 타일을 순회하는 비용보다 더 많은 추가 비용을 빠르게 합산 할 수 있습니다. 그러나 그의 핵심 아이디어는 정확합니다!

"모든"최적의 경로 (가장 짧은 길이)를 계산 한 다음 다른 휴리스틱으로 경로 중 하나를 선택하도록 A *를 쉽게 적용 할 수 있습니다. 그러나 문제가 있습니다. 경로가 길면 최적 길이의 솔루션이 많이있을 수 있습니다. 이로 인해 A * 알고리즘이 다른 모든 솔루션도 계산하는 데 훨씬 오래 걸립니다. 그리드 때문입니다. 90도 대신 80도를 걷을 수 없으므로 하나의 최적 솔루션 대신 여러 차선의 솔루션이 생성됩니다. 상상력을 발휘하기 위해 장애물이없는지도를 상상해보십시오. x- 거리는 2이고 y- 거리는 3입니다. 즉, 모든 최단 경로에는 2 개의 대각선 이동과 1 개의 직선 이동이 있습니다. 이 간단한 경로에는 SDD, DSD, DDS (여기서 D = 대각선, S = 직선)의 세 가지 유효한 조합이 있습니다. 실제 "재미"는 다음과 같은 경로가있을 때 이미 시작됩니다. 3 개의 직선 및 2 개의 대각선 이동 : SSSDD, SSDSD, SSDDS, SDSSD, SDSDS, SDDSS, DSSSD, DSSDS, DSDSS, DDSSS (내가 놓치지 않은 경우 가장 짧은 경로의 10 가지 변형). 나는 당신이 아이디어를 가지고 있어야한다고 생각합니다 ...

따라서 적은 수의 솔루션 (또는 하나의 솔루션 만)이 "최적"인 방식으로 비용 함수를 조정하여이 문제를 해결해야합니다.

비용 함수 적용

필립이 자신의 모범 공식에서 제안한대로 적응하면 훨씬 더 나은 결과를 얻을 수 있지만 여전히 몇 가지 문제가 있습니다. 경로를 따라 더 짧거나 더 긴 "부분"을 균등하게 분배하지 않습니다. 즉, 방향 변경이 경로의 시작 부분에서 더 자주 또는 그 반대로 변경됩니다.

또한, 배우가 끝까지 "돌아가도록"하는 경로는 인간에 의해 관찰 될 때 차선책 인 것처럼 보인다. 회전 애니메이션을 표시하는 데 시간이 걸리므로 속도가 느려 야합니다.

그러나 비용에 플로트를 사용하는 대신 "2 차 비용"또는 2 차 정렬 기준을 구현할 수 있습니다. 1 차 원가가 동일하면 2 차 원가를 사용하여 어떤 솔루션을 선호할지 추정합니다. 이로 인해 기본 비용 (그리드 측정의 경로 길이)이 증가하지는 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.