Python 基于A*算法路径规划实现,采用欧氏距离进行计算,起点终点和路径障碍由用户输入,并根据用户输入自动调节地图大小,最后动态显示路径
时间: 2024-03-21 20:43:28 浏览: 104
以下是基于 A* 算法实现路径规划的 Python 代码,可以根据用户输入自动调节地图大小,并动态显示路径:
```python
import heapq
import math
import tkinter as tk
class Node:
def __init__(self, x, y, obstacle=False):
self.x = x
self.y = y
self.obstacle = obstacle
self.g = 0
self.h = 0
self.parent = None
def __lt__(self, other):
return self.g + self.h < other.g + other.h
class AStar:
def __init__(self, start, end, width, height, obstacles):
self.start = start
self.end = end
self.width = width
self.height = height
self.obstacles = obstacles
self.open_list = []
self.closed_list = []
self.grid = [[Node(x, y) for y in range(height)] for x in range(width)]
for x, y in obstacles:
self.grid[x][y].obstacle = True
def heuristic(self, node):
return math.sqrt((node.x - self.end.x)**2 + (node.y - self.end.y)**2)
def get_neighbors(self, node):
neighbors = []
for dx in range(-1, 2):
for dy in range(-1, 2):
if dx == 0 and dy == 0:
continue
x = node.x + dx
y = node.y + dy
if x < 0 or x >= self.width or y < 0 or y >= self.height:
continue
if self.grid[x][y].obstacle:
continue
neighbors.append(self.grid[x][y])
return neighbors
def find_path(self):
heapq.heappush(self.open_list, self.start)
while len(self.open_list) > 0:
current = heapq.heappop(self.open_list)
if current == self.end:
path = []
while current is not None:
path.append((current.x, current.y))
current = current.parent
return path[::-1]
self.closed_list.append(current)
for neighbor in self.get_neighbors(current):
if neighbor in self.closed_list:
continue
tentative_g = current.g + math.sqrt((neighbor.x - current.x)**2 + (neighbor.y - current.y)**2)
if neighbor not in self.open_list or tentative_g < neighbor.g:
neighbor.g = tentative_g
neighbor.h = self.heuristic(neighbor)
neighbor.parent = current
if neighbor not in self.open_list:
heapq.heappush(self.open_list, neighbor)
return None
class PathFinder:
def __init__(self, master):
self.master = master
self.canvas = tk.Canvas(master, width=600, height=600, bg="white")
self.canvas.pack()
self.canvas.bind("<Button-1>", self.on_click)
self.canvas.bind("<Button-3>", self.on_right_click)
self.start = None
self.end = None
self.obstacles = set()
self.path = None
def on_click(self, event):
x, y = event.x // 20, event.y // 20
if self.start is None:
self.start = Node(x, y)
self.draw_node(x, y, "green")
elif self.end is None:
self.end = Node(x, y)
self.draw_node(x, y, "red")
elif (x, y) not in self.obstacles:
self.obstacles.add((x, y))
self.draw_node(x, y, "black")
def on_right_click(self, event):
x, y = event.x // 20, event.y // 20
if self.start is not None and self.start.x == x and self.start.y == y:
self.start = None
self.erase_node(x, y)
elif self.end is not None and self.end.x == x and self.end.y == y:
self.end = None
self.erase_node(x, y)
elif (x, y) in self.obstacles:
self.obstacles.remove((x, y))
self.erase_node(x, y)
def draw_node(self, x, y, color):
self.canvas.create_rectangle(x*20, y*20, (x+1)*20, (y+1)*20, fill=color)
def erase_node(self, x, y):
self.canvas.create_rectangle(x*20, y*20, (x+1)*20, (y+1)*20, fill="white")
def find_path(self):
width = 600 // 20
height = 600 // 20
a_star = AStar(self.start, self.end, width, height, self.obstacles)
self.path = a_star.find_path()
if self.path is not None:
for x, y in self.path:
self.draw_node(x, y, "blue")
def clear(self):
self.canvas.delete("all")
self.start = None
self.end = None
self.obstacles.clear()
self.path = None
def run(self):
self.master.mainloop()
if __name__ == "__main__":
root = tk.Tk()
path_finder = PathFinder(root)
find_path_button = tk.Button(root, text="Find Path", command=path_finder.find_path)
find_path_button.pack(side=tk.LEFT)
clear_button = tk.Button(root, text="Clear", command=path_finder.clear)
clear_button.pack(side=tk.LEFT)
path_finder.run()
```
当你运行这段代码时,它将会显示一个界面,你可以在其中用鼠标左键单击来设置起点、终点和障碍物。然后单击“Find Path”按钮来寻找路径,路径会显示为蓝色。如果需要重新开始,可以单击“Clear”按钮清除画布。
阅读全文