Python 3.x python 3d A*寻路无限循环
我正在尝试适应我发现的一个应用程序,我想象我只需要添加一个轴。问题是脚本似乎被卡住了。有人能告诉我我做错了什么,以及我如何将A*与3d矩阵(I j k)结合使用吗 这是我更改的A*函数的部分Python 3.x python 3d A*寻路无限循环,python-3.x,path-finding,a-star,Python 3.x,Path Finding,A Star,我正在尝试适应我发现的一个应用程序,我想象我只需要添加一个轴。问题是脚本似乎被卡住了。有人能告诉我我做错了什么,以及我如何将A*与3d矩阵(I j k)结合使用吗 这是我更改的A*函数的部分 for new_position in [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]: # Adjacent squares, (-1, -1), (-1, 1), (1, -
for new_position in [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]: # Adjacent squares, (-1, -1), (-1, 1), (1, -1), (1, 1)]: # Adjacent squares removed to ignor diagonal movement
# Get node position
node_position = (current_node.position[0] + new_position[0], current_node.position[1] + new_position[1], current_node.position[2] + new_position[2])
# Make sure within range
if node_position[0] > (len(maze) - 1) or node_position[0] < 0 or node_position[1] > (len(maze[len(maze)-1]) -1) or node_position[1] < 0 or node_position[2] > (len(maze) - 1) or node_position[2] < 0 or node_position[2] > (len(maze[len(maze)-1]) -1):
continue
# Make sure walkable terrain
if maze[node_position[0]][node_position[1]][node_position[2]] != 0:
continue
对于[(0,0,0),(0,0,1),(0,1,0),(0,1,1),(1,0,0),(1,0,1),(1,1,0),(1,1,1)]中的新#u位置:#相邻的正方形,(-1,-1),(-1,1),(1,1)]:#相邻的正方形移到ignor对角线运动
#获取节点位置
节点位置=(当前节点位置[0]+新位置[0],当前节点位置[1]+新位置[1],当前节点位置[2]+新位置[2])
#确保在范围内
如果节点位置[0]>(len(maze)-1)或节点位置[0]<0或节点位置[1]>(len(maze[len(maze)-1])或节点位置[1]<0或节点位置[2]>(len(maze)-1)或节点位置[2]<0或节点位置[2]>(len(maze[len(maze)-1])-1):
持续
#确保可行走的地形
如果迷宫[节点位置[0]][节点位置[1]][节点位置[2]!=0:
持续
原来是:
for new_position in [(0, -1), (0, 1), (-1, 0), (1, 0), (-1, -1), (-1, 1), (1, -1), (1, 1)]: # Adjacent squares
# Get node position
node_position = (current_node.position[0] + new_position[0], current_node.position[1] + new_position[1])
# Make sure within range
if node_position[0] > (len(maze) - 1) or node_position[0] < 0 or node_position[1] > (len(maze[len(maze)-1]) -1) or node_position[1] < 0:
continue
# Make sure walkable terrain
if maze[node_position[0]][node_position[1]] != 0:
continue
对于[(0,-1),(0,1),(-1,0),(1,0),(-1,-1),(-1,1),(1,1)]中的新位置:
#获取节点位置
节点位置=(当前节点位置[0]+新位置[0],当前节点位置[1]+新位置[1])
#确保在范围内
如果节点位置[0]>(len(迷宫)-1)或节点位置[0]<0或节点位置[1]>(len(迷宫)[len(迷宫)-1])-1)或节点位置[1]<0:
持续
#确保可行走的地形
如果迷宫[节点位置[0]][节点位置[1]!=0:
持续
这是我修改的全部脚本:
import numpy as np
class Node():
"""A node class for A* Pathfinding"""
def __init__(self, parent=None, position=None):
self.parent = parent
self.position = position
self.g = 0
self.h = 0
self.f = 0
def __eq__(self, other):
return self.position == other.position
def astar(maze, start, end):
"""Returns a list of tuples as a path from the given start to the given end in the given maze"""
# Create start and end node
start_node = Node(None, start)
start_node.g = start_node.h = start_node.f = 0
end_node = Node(None, end)
end_node.g = end_node.h = end_node.f = 0
# Initialize both open and closed list
open_list = []
closed_list = []
# Add the start node
open_list.append(start_node)
# Loop until you find the end
while len(open_list) > 0:
# Get the current node
current_node = open_list[0]
current_index = 0
for index, item in enumerate(open_list):
if item.f < current_node.f:
current_node = item
current_index = index
# Pop current off open list, add to closed list
open_list.pop(current_index)
closed_list.append(current_node)
# Found the goal
if current_node == end_node:
path = []
current = current_node
while current is not None:
path.append(current.position)
current = current.parent
return path[::-1] # Return reversed path
# Generate children
children = []
for new_position in [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]: # Adjacent squares, (-1, -1), (-1, 1), (1, -1), (1, 1)]: # Adjacent squares removed to ignor diagonal movement
# Get node position
node_position = (current_node.position[0] + new_position[0], current_node.position[1] + new_position[1], current_node.position[2] + new_position[2])
# Make sure within range
if node_position[0] > (len(maze) - 1) or node_position[0] < 0 or node_position[1] > (len(maze[len(maze)-1]) -1) or node_position[1] < 0 or node_position[2] > (len(maze) - 1) or node_position[2] < 0 or node_position[2] > (len(maze[len(maze)-1]) -1):
continue
# Make sure walkable terrain
if maze[node_position[0]][node_position[1]][node_position[2]] != 0:
continue
# Create new node
new_node = Node(current_node, node_position)
# Append
children.append(new_node)
# Loop through children
for child in children:
# Child is on the closed list
for closed_child in closed_list:
if child == closed_child:
continue
# Create the f, g, and h values
child.g = current_node.g + 1
child.h = ((child.position[0] - end_node.position[0]) ** 2) + ((child.position[1] - end_node.position[1]) ** 2)+((child.position[2] - end_node.position[2]) ** 2)
child.f = child.g + child.h
# Child is already in the open list
for open_node in open_list:
if child == open_node and child.g > open_node.g:
continue
# Add the child to the open list
open_list.append(child)
def main():
maze = np.zeros((12,12,12))
start = (10, 9, 9)
end = (1, 1, 1)
path = astar(maze, start, end)
print(path)
if __name__ == '__main__':
main()
将numpy导入为np
类节点():
“”“用于*寻路的节点类”“”
定义初始化(self,parent=None,position=None):
self.parent=parent
self.position=位置
self.g=0
self.h=0
self.f=0
定义(自身、其他):
返回self.position==其他.position
def astar(迷宫、开始、结束):
“”“返回元组列表,作为给定迷宫中从给定起点到给定终点的路径”“”
#创建开始和结束节点
开始\节点=节点(无,开始)
开始节点。g=开始节点。h=开始节点。f=0
结束\节点=节点(无,结束)
end_node.g=end_node.h=end_node.f=0
#初始化打开和关闭列表
打开列表=[]
已关闭的_列表=[]
#添加开始节点
打开\u列表。追加(开始\u节点)
#循环直到找到终点
而len(开放列表)>0:
#获取当前节点
当前\u节点=打开\u列表[0]
当前指数=0
对于索引,枚举中的项(打开列表):
如果.f项<当前节点.f:
当前节点=项目
当前索引=索引
#弹出当前关闭打开列表,添加到关闭列表
打开\u列表.pop(当前\u索引)
关闭\u列表。追加(当前\u节点)
#找到目标
如果当前_节点==结束_节点:
路径=[]
当前=当前节点
虽然当前值不是“无”:
path.append(当前位置)
current=current.parent
返回路径[:-1]#返回反向路径
#生子
儿童=[]
对于[(0,0,0),(0,0,1),(0,1,0),(0,1,1),(1,0,0),(1,0,1),(1,1,0),(1,1,1)]中的新#u位置:#相邻正方形,(-1,-1),(-1,1),(-1,1)]:#相邻正方形被移到ignor对角线运动
#获取节点位置
节点位置=(当前节点位置[0]+新位置[0],当前节点位置[1]+新位置[1],当前节点位置[2]+新位置[2])
#确保在范围内
如果节点位置[0]>(len(maze)-1)或节点位置[0]<0或节点位置[1]>(len(maze[len(maze)-1])或节点位置[1]<0或节点位置[2]>(len(maze)-1)或节点位置[2]<0或节点位置[2]>(len(maze[len(maze)-1])-1):
持续
#确保可行走的地形
如果迷宫[节点位置[0]][节点位置[1]][节点位置[2]!=0:
持续
#创建新节点
新节点=节点(当前节点,节点位置)
#附加
附加(新的_节点)
#环游儿童
对于儿童中的儿童:
#孩子在关闭名单上
对于已关闭\u列表中的已关闭\u子项:
如果子项==关闭的子项:
持续
#创建f、g和h值
child.g=当前_节点.g+1
child.h=((child.position[0]-end_node.position[0])**2+((child.position[1]-end_node.position[1])**2+((child.position[2]-end_node.position[2])**2)
child.f=child.g+child.h
#子项已在打开列表中
对于“打开”列表中的“打开”节点:
如果child==open_node和child.g>open_node.g:
持续
#将子项添加到打开列表中
打开\u列表。追加(子项)
def main():
迷宫=np.零((12,12,12))
开始=(10,9,9)
结束=(1,1,1)
路径=astar(迷宫、开始、结束)
打印(路径)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()
A*可以处理任意数量的尺寸;这是一个图形遍历算法,无论问题空间有多少维度,将一个位置连接到另一个位置仍然会生成一个图形
但是,在生成新节点时有两个问题
- 您在列表中包含了
,因此没有更改。您不断将当前位置放回队列中以供考虑。这只是一项繁忙的工作,因为当前职位已经在关闭列表中(0,0,0)
- 你永远不会从你的坐标中减去,你只会加上。所以你的
,x
deltas = [ (0, 0, 0), # no change, (0, 0, 1), (0, 1, 0), (1, 0, 0), # add to a single axis (0, 1, 1), (1, 0, 1), (1, 1, 0), # add to two axes (1, 1, 1) # move in all 3 directions at once. ] for delta in deltas: # ...
from itertools import product # combinations of -1, 0 and 1, filtering out the (0, 0, 0) case: deltas = [d for d in product((-1, 0, 1), repeat=3) if any(d)]
# Adjacent squares removed to ignor diagonal movement
# movement without diagonals deltas = [ (1, 0, 0), (-1, 0, 0), # only x (0, 1, 0), (0, -1, 0), # only y (0, 0, 1), (0, 0, -1), # only z ]
def possible_moves(self, map): x, y, z = self.x, self.y, self.z for dx, dy, dz in DELTAS: newx, newy, newz = x + dx, y + dy, z + dz try: if maze[newx][newy][newz] != 0: yield Node(self, (newx, newy, newz)) except IndexError: # not inside the maze anymore, ignore pass
# Loop through children for child in current_node.possible_moves(map): # Child is on the closed list for closed_child in closed_list: if child == closed_child: continue # etc.