【发布时间】:2020-01-12 21:15:52
【问题描述】:
为了保持我的编码清晰,我从一些典型的谜题开始。我找到了 A* 算法的实现。下一步将是对其进行调整,以便可以移除 N 个障碍物以找到最佳路径。如果迷宫如下图所示,其中 1 代表障碍:
[[0, 1, 1, 0],
[0, 0, 0, 0],
[1, 1, 1, 0],
[1, 0, 1, 0]]
A* 实现: 导入堆
class Cell:
def __init__(self,x,y,passable):
self.passable = passable
self.x = x
self.y = y
self.g = 0
self.h = 0
self.f = 0
self.parent = None
def __repr__(self):
return 'Cell((%s, %s), %s)' % (self.x, self.y, self.passable)
class Maze:
def __init__(self,maze_map):
self.maze_map = maze_map
self.cells = []
self.maze_height = None
self.maze_width = None
self.cells_to_visit = []
heapq.heapify(self.cells_to_visit)
self.cells_visited = set()
def initialize_cells(self):
self.maze_height = len(self.maze_map)
self.maze_width = len(self.maze_map[0])
door_start = (0,0)
door_end = (self.maze_height-1,self.maze_width-1)
for h in range(self.maze_height):
for w in range(self.maze_width):
if self.maze_map[h][w] == 0:
passable = True
else:
passable = False
self.cells.append(Cell(w,h,passable))
self.start = self.get_cell(*door_start)
self.end = self.get_cell(*door_end)
def calculate_heuristic(self,cell):
cost = 10
return cost * (abs(cell.x - self.end.x) + abs(cell.y - self.end.y))
def get_cell(self, x, y):
return self.cells[x * self.maze_height + y]
def get_path(self):
cell = self.end
path = [(cell.x, cell.y)]
while cell.parent is not self.start:
cell = cell.parent
path.append((cell.x, cell.y))
path.append((self.start.x, self.start.y))
path.reverse()
return path
def update_cell(self, adj, cell):
adj.g = cell.g + 10
adj.h = self.calculate_heuristic(adj)
adj.parent = cell
adj.f = adj.h + adj.g
def get_adjacent_cells(self,cell):
cells = []
if cell.x < self.maze_width-1:
cells.append(self.get_cell(cell.x+1, cell.y))
if cell.y > 0:
cells.append(self.get_cell(cell.x, cell.y-1))
if cell.x > 0:
cells.append(self.get_cell(cell.x-1, cell.y))
if cell.y < self.maze_width-1:
cells.append(self.get_cell(cell.x, cell.y+1))
return cells
def solve(self):
heapq.heappush(self.cells_to_visit, self.start)
while len(self.cells_to_visit):
cell = heapq.heappop(self.cells_to_visit)
self.cells_visited.add(cell)
if cell is self.end:
return self.get_path()
adj_cells = self.get_adjacent_cells(cell)
for adj_cell in adj_cells:
if adj_cell not in self.cells_visited:
if (adj_cell.f, adj_cell) in self.cells_to_visit:
if adj_cell.g > cell.g + 10:
self.update_cell(adj_cell, cell)
else:
self.update_cell(adj_cell, cell)
heapq.heappush(self.cells_to_visit, adj_cell)
if __name__ == "__main__":
m = [[0, 1, 1, 0],
[0, 0, 1, 0],
[1, 1, 1, 0],
[1, 0, 1, 0]]
N = 1 #allowed to remove 1 obstacle
maze = Maze(map,N)
maze.initialize_cells()
maze.solve()
m = [[0, 1, 1, 0],
[0, 0, 1, 0],
[1, 1, 1, 1],
[1, 0, 1, 0]]
N = 2 #allowed to remove 2 obstacles
maze = Maze(map,N)
maze.initialize_cells()
maze.solve()
从消除一个障碍的可能性开始,让它泛化到 N 有多容易?另外,应该如何实现这样的事情?
提前谢谢你。
【问题讨论】:
标签: python python-3.x a-star maze