[Daily Contents] A star 알고리즘
MAP
- S에서 E까지 가는 최단경로
- 평행 이동거리 : 10
- 대각선 이동거리 : 14
- 평행한 이웃 Node가 Block >> 대각선 방향으로 이동 X
Node 4-state
- Close : 가본 곳
- Open : 발견됨, 가 봐야 될 곳
- Empty : 미 발견됨, 안 가봄
- Block : 갈 수 없는 곳
Step
Step 1
S1 : 도착한 노드는 CLose state
Step 2
S2 : 주변 Node 탐색, State에 따라
- EMPTY => OPEN state
- BLOCK => Nothing(대각선 Node 포함)
- CLOSE => Nothing
- OPEN => -G 값이 작다 => 부모 Node 바꿈
-G 값이 크다 => Nothings
Step 3
S3 : Open Node 중, 최소 F값 Node로 이동
- G : 출발지에서 이동한 거리
- H : 도착지까지 남은 거리 => 멘하튼 Distance 방식, 직교하는 거리
- F = G + H
Step 1~3
- 반복하여 수행
- 도착 Node를 찾으면 Success
Failed Case
- 반복해도 Open Node는 줄어들고 Close Node만 많아지다가 모든 노드가 Close Node로 바뀐 후 Fail
Source URL
- https://github.com/sweetchild222/vanilla-algorithm
data = [
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, -1, 0, 0, 0,
0, 0, 0, 0, -1, 0, 0, 0,
0, 0, 0, 0, -1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0]
widrh = 8
height = 6
start = Point(2, 3)
stop = Point(6, 3)
map = Map(data, width, height, stop)
node = aStar(start, stop, map)
while node:
print(node.getPoint())
node = node.getParent()
(6, 3)
(6, 2)
(5, 1)
(4, 1)
(3, 1)
(3, 2)
(2, 3)
class State(Enum):
EMPTY = 0
OPEN = 1
CLOSE = 2
BLOCK = 3
class Node:
def __init__(self, point, h):
self.state = State.EMPTY
self.point = point
self.h = h
self.parent = None
def aStar(start, stop, nodeMap):
openList = OpenList()
node = map.getNode(start)
while True:
node.setClose()
if node.getPoint() == stop:
return node
childList = lookAround(node, nodeMap)
openList.append(childList)
node = openList.minCostFnode()
if node is None:
return None
- S1 : 도착한 Node는 Close state
- S2 : 주변 Node 탐색, State에 따라…
- S3 : Open Node 중, 최소 F값 Node로 이동
def lookAround(node, map):
childDelta = [Point(1, 0), Point(1, -1), Point(0, -1), Point(-1, -1),
Point(-1, 0), Point(-1, 1), Point(0, 1), Point(1, 1)]
openList = []
for delta in childDelta:
childPoint = node.getPoint() + delta
childNode = map.getNode(childPoint)
if childNode is None:
continue
if neighborBlock(node, delta, map) is True:
continue
if childNode.isBlock():
continue
elif childNode.isClose():
continue
elif childNode.isEmpty():
childNode.setParent(node)
childNode.setOpen()
openList.append(childNode)
elif childNode.isOpen():
currentCostG = childNode.costG()
newCostG = childNode.calcCostG(node)
if currentCostG > newCostG:
childNode.setParent(node)
else:
print('error!')
return openList
S2 : 주변 Node 탐색, State에 따라
- EMPTY => OPEN state
- BLOCK => Nothing(대각선 Node 포함)
- CLOSE => Nothing
- OPEN => -G 값이 작다 => 부모 Node 바꿈
-G 값이 크다 => Nothings
댓글남기기