我正在为一个机器人项目制作前端(一个“自主”汽车,它使用一些传感器和从SVG文件生成的地图进行本地化)。
为了使机器人可控,我们必须在当前位置和目标位置之间生成路径。我使用最简单的算法:A*算法。
但是我发现了一些奇怪的结果:汽车倾向于按45度的倍数行驶,并且还有一个特别令人烦恼的问题:一些生成的路径非常嘈杂!
请查看此示例中橙色矩形附近的嘈杂路径:
有没有办法避免这些奇怪/嘈杂的结果?最终,我们想要建立具有最小航向角更改次数的路径。(汽车可以旋转而无需移动,因此我们不需要任何路径“平滑处理”)。
这是我的A*实现:
def search(self, begin, goal):
if goal.x not in range(self.width) or goal.y not in range(self.height):
print "Goal is out of bound"
return []
elif not self.grid[begin.y][begin.x].reachable:
print "Beginning is unreachable"
return []
elif not self.grid[goal.y][goal.x].reachable:
print "Goal is unreachable"
return []
else:
self.cl = set()
self.ol = set()
curCell = begin
self.ol.add(curCell)
while len(self.ol) > 0:
# We choose the cell in the open list having the minimum score as our current cell
curCell = min(self.ol, key = lambda x : x.f)
# We add the current cell to the closed list
self.ol.remove(curCell)
self.cl.add(curCell)
# We check the cell's (reachable) neighbours :
neighbours = self.neighbours(curCell)
for cell in neighbours:
# If the goal is a neighbour cell :
if cell == goal:
cell.parent = curCell
self.path = cell.path()
self.display()
self.clear()
return self.path
elif cell not in self.cl:
# We process the cells that are not in the closed list
# (processing <-> calculating the "F" score)
cell.process(curCell, goal)
self.ol.add(cell)
编辑 1:根据广泛需求,这里是得分计算函数(过程):
def process(self, parent, goal):
self.parent = parent
self.g = parent.distance(self)
self.h = self.manhattanDistance(goal)
self.f = self.g + self.h
编辑 这里是邻居方法(根据 user1884905 的答案进行了更新):
def neighbours(self, cell, radius = 1, unreachables = False, diagonal = True):
neighbours = set()
for i in xrange(-radius, radius + 1):
for j in xrange(-radius, radius + 1):
x = cell.x + j
y = cell.y + i
if 0 <= y < self.height and 0 <= x < self.width and ( self.grid[y][x].reachable or unreachables ) and (diagonal or (x == cell.x or y == cell.y)) :
neighbours.add(self.grid[y][x])
return neighbours
这看起来很复杂,但实际上只是给出一个细胞的8个邻居(包括对角线邻居);它还可以使用不同于1的半径,因为它用于其他功能。
并且可以根据是否使用对角线邻居进行距离计算 :)
def manhattanDistance(self, cell):
return abs(self.x - cell.x) + abs(self.y - cell.y)
def diagonalDistance(self, cell):
xDist = abs(self.x - cell.x)
yDist = abs(self.y - cell.y)
if xDist > yDist:
return 1.4 * yDist + (xDist - yDist)
else:
return 1.4 * xDist + (yDist - xDist)
heuristic_cost_estimate()
函数。你的代码没有这样做,所以它找不到最短路径。 - martineau