简体   繁体   English

A *算法找不到最短路径

[英]A* Algorithm does not find shortest path

I am trying to implement the A* algorithm in python but have hit a problem when trying to find the path of this map: 我试图在python中实现A *算法,但在尝试查找此映射的路径时遇到了问题:

X X X X X X X     S = Start
0 0 0 X 0 0 0     E = End
0 S 0 X 0 E 0     X = Wall
0 0 0 X 0 0 0
0 0 0 0 0 0 0

I am using the Manhattan method. 我正在使用曼哈顿方法。 My implementation does find a path, but not the shortest one. 我的实现确实找到了一条路径,但不是最短路径。 The error starts on it's second move -- after moving right. 错误从第二步开始 - 向右移动后开始。 At this point it can move up and the heuristic cost would be four (three right, one down) or down (three right, one up). 此时它可以向上移动,启发式成本将是四(三个右,一个下)或下(三个右,一个上)。 Is there a way so it chooses down to get the shortest path? 有没有办法让它选择下来获得最短的路径?

Code: 码:

class Node:
    def __init__(self, (x, y), g, h, parent):
        self.x = x
        self.y = y
        self.g = g
        self.h = h
        self.f = g+h
        self.parent = parent

    def __eq__(self, other):
        if other != None:
            return self.x == other.x and self.y == other.y
        return False

    def __lt__(self, other):
        if other != None:
            return self.f < other.f
        return False

    def __gt__(self, other):
        if other != None:
            return self.f > other.f
        return True

    def __str__(self):
        return "(" + str(self.x) + "," + str(self.y) + ") " + str(self.f)

def find_path(start, end, open_list, closed_list, map, no_diag=True, i=1):
    closed_list.append(start)
    if start == end or start == None:
         return closed_list
     new_open_list = []
     for x, y in [(-1,1),(-1,-1),(1,-1),(1,1),(0,-1),(0,1),(-1,0),(1,0)]:
        full_x = start.x + x
        full_y = start.y + y
        g = 0
        if x != 0 and y != 0:
            if no_diag:
                continue
            g = 14
        else:
            g = 10
        h = 10 * (abs(full_x - end.x) + abs(full_y - end.y))
        n = Node((full_x,full_y),g,h,start)
        if 0 <= full_y < len(map) and 0 <= full_x < len(map[0]) and map[full_y][full_x] != 1 and n not in closed_list:
            if n in open_list:
                if open_list[open_list.index(n)].g > n.g:
                    new_open_list.append(n)
                else:
                    new_open_list.append(open_list[open_list.index(n)])
            else:
                new_open_list.append(n)
    if new_open_list == None or len(new_open_list) == 0:
        return find_path(start.parent, end, open_list, closed_list, map, no_diag, i-1)
    new_open_list.sort()
    return find_path(new_open_list[0], end, new_open_list, closed_list, map, no_diag)

You seem to be constructing a new open list for each node, which contains only that node's neighbors. 您似乎正在为每个节点构建一个新的打开列表,该列表仅包含该节点的邻居。 This essentially makes your search a form of a depth-first search, while A* should be a best-first search. 这实质上使您的搜索成为深度优先搜索的形式,而A *应该是最好的搜索。

You need to use one open list which will be updated with each node's neighbors as you visit that node. 您需要使用一个打开的列表,当您访问该节点时,该列表将随每个节点的邻居进行更新。 The old nodes in the open list must remain there until they are traversed and moved to the closed list. 打开列表中的旧节点必须保留在那里,直到它们被遍历并移动到关闭列表中。

Regarding what you said in your question, It's OK for the search to try moving up before down (since according to the heuristic, they are the same distance from the goal). 关于你在你的问题中所说的,搜索尝试在向下移动之前是可以的(因为根据启发式,它们与目标的距离相同)。 What matters is that in the end, the path chosen will be the shortest. 重要的是,最终选择的路径将是最短的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM