需要更改A *算法,以便与代理轮换一起使用

时间:2019-04-23 18:59:51

标签: python artificial-intelligence path-finding

我正在写一个简单的A *算法来查找最短路径。但是我需要更复杂的东西。代理只能前进并旋转(90度)。它会影响路径还是我可以使用简单的A *? 谢谢大家


def astar(maze, start, end):

    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

    open_list = []
    closed_list = []

    open_list.append(start_node)
    while len(open_list) > 0:
        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

        open_list.pop(current_index)
        closed_list.append(current_node)
        if current_node == end_node:
            path = []
            current = current_node
            while current is not None:
                path.append(current.position)
                current = current.parent
            return path[::-1]
        children = []
        for new_position in [(0, -1), (0, 1), (-1, 0), (1, 0), (-1, -1), (-1, 1), (1, -1), (1, 1)]:
            node_position = (current_node.position[0] + new_position[0], current_node.position[1] + new_position[1])
            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
            if maze[node_position[0]][node_position[1]] != 0:
                continue
            new_node = Node(current_node, node_position)
            children.append(new_node)
        for child in children:
            for closed_child in closed_list:
                if child == closed_child:
                    continue
            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.f = child.g + child.h
            for open_node in open_list:
                if child == open_node and child.g > open_node.g:
                    continue
            open_list.append(child)

2 个答案:

答案 0 :(得分:1)

这里的主要问题是A *算法需要意识到以下事实:“位于面向d 1 方向的位置(x,y)”和“位于面向d 2 方向的(x,y)位置。”如果算法不知道这一点,则无法为您提供最佳的后续说明。

解决这个问题的一种方法是,假设您的世界不是2D网格,而是实际上是一个3D空间,其中包含4个相互叠放的2D网格副本。就像您在2D空间中的位置由当前(x,y)坐标组成一样,在3D空间中的位置也由当前(x,y)坐标以及您面对的方向组成。

想象一下在这个空间中移动意味着什么。对于动作,您有两个选择-“移动”或“旋转90°”“移动”动作将使您在当前所在的2D切片中向前移动一步,其中“前进”的含义不同换句话说,“移动”将使您仅在X / Y平面内移动,并保持方向固定。 “转弯”操作将使您的X / Y位置保持固定,但会更改您所处的平面(基于您当时正好面对的方向)。

如果您将此信息明确编码到搜索中,则A *可以使用它来找到最佳的路径。您需要定义一些新的启发式方法,以估计距目标的距离。一种选择是假设没有围墙,并确定要达到目标必须采取的步骤以及所需的旋转次数。届时,A *可以通过您的启发式方法引导您的搜索,从而为您提供最佳的跟踪途径。

更一般而言,许多形式为“我在世界上有位置,加上一些额外的状态(方向,速度等)”的问题可以从2D空间中的寻路转换为3D空间中的寻路,维度将是那条额外的信息。或者,如果您有多条额外的信息,则可能会扩展到4D或5D空间。

希望这会有所帮助!

答案 1 :(得分:0)

要做的第一件事是将源代码分为两个功能:代理程序的正向模型和(路径)规划算法本身。在正向模型中,指定了代理具有三个可能的动作(向前,向左旋转,向右旋转)。 A *计划者为代理创建游戏树。可能的顺序是:向左,向前,向前。

这不是一个经典的路径规划问题,而是一个AI规划问题。与常规A *寻路算法相比,实现这种两层系统更加复杂,因为旋转动作不会使代理更接近目标。要确定模拟行动是否改善了局势,还是后退一步,决定起来就更加复杂。

在现实生活中,即使将描述的分离为前向模型和计划器也无法解决问题,因为地图中的状态空间会非常快地增长。需要其他启发法来指导A *计划者朝最佳方向发展。