Python 3.x python 3d 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, -

我正在尝试适应我发现的一个应用程序,我想象我只需要添加一个轴。问题是脚本似乎被卡住了。有人能告诉我我做错了什么,以及我如何将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, -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.