您好,登錄后才能下訂單哦!
這篇文章主要介紹了Python3 A*尋路算法的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
直接上代碼吧!
# -*- coding: utf-8 -*- import math import random import copy import time import sys import tkinter import threading # 地圖 tm = [ '############################################################', '#S............................#............#.....#.........#', '#..........#..................#......#.....#.....#.........#', '#..........#..................#......#.....#.....#.........#', '#..........#..................#......#.....#.....#.........#', '#..........#.........................#.....#.....#.........#', '#..........#..................#......#.....#...............#', '#..#########..................#......#.....#.....#.........#', '#..#..........................#......#.....#.....#.........#', '#..#..........................#......#.....#.....#.........#', '#..############################......#.....#.....#.........#', '#.............................#......#.....#.....#.........#', '#.............................#......#...........#.........#', '#######.##################################################.#', '#....#........#.................#.............#............#', '#....#........#........#........#.............#............#', '#....####.#####........#........#.............#............#', '#.........#............#........#.............#............#', '#.........#............#........#.............#............#', '#.........#............#........#.............#............#', '#.........#............#........#.............#............#', '#.........#............#........#.............#............#', '#.........#............#........####.#######.##............#', '#.........#............#........#....#.......#.............#', '#.........#............#........#....#.......#.............#', '#......................#........#....#.......#.............#', '#.........#............#........##.########..#.............#', '#.........#............#..................#..########.######', '#.........#............#..................#...............E#', '############################################################'] # 存儲搜索時的地圖 test_map = [] #----------- 開放列表和關閉列表的元素類型,parent用來在成功的時候回溯路徑 ----------- class Node_Elem: def __init__(self, parent, x, y, dist): self.parent = parent # 回溯父節點 self.x = x # x坐標 self.y = y # y坐標 self.dist = dist # 從起點到此位置的實際距離 #----------- A*算法 ----------- class A_Star: def __init__(self, root, s_x, s_y, e_x, e_y, w=60, h=30): self.s_x = s_x # 起點x self.s_y = s_y # 起點y self.e_x = e_x # 終點x self.e_y = e_y # 終點y self.open = [] # open表 self.close = [] # close表 self.path = [] # path表 # 創建畫布 self.root = root # 畫布根節點 self.width = w # 地圖w,默認60 self.height = h # 地圖h,默認30 self.__r = 3 # 半徑 # Tkinter.Canvas self.canvas = tkinter.Canvas( root, width=self.width * 10 + 100, height=self.height * 10 + 100, bg="#EBEBEB", # 背景白色 xscrollincrement=1, yscrollincrement=1 ) self.canvas.pack(expand=tkinter.YES, fill=tkinter.BOTH) self.title("A*迷宮算法(e:開始搜索或退出)") self.__bindEvents() self.new() # 按鍵響應程序 def __bindEvents(self): self.root.bind("e", self.quite) # 退出程序 # 退出程序 def quite(self, evt): self.root.destroy() # 更改標題 def title(self, s): self.root.title(s) # 初始化 def new(self): node = self.canvas.create_oval(100 - self.__r, 20 - self.__r, 100 + self.__r, 20 + self.__r, fill="#ff0000", outline="#ffffff", tags="node", ) self.canvas.create_text(130, 20, text=u'Wall', fill='black' ) node = self.canvas.create_oval(200 - self.__r, 20 - self.__r, 200 + self.__r, 20 + self.__r, fill="#00ff00", outline="#ffffff", tags="node", ) self.canvas.create_text(230, 20, text=u'Path', fill='black' ) node = self.canvas.create_oval(300 - self.__r, 20 - self.__r, 300 + self.__r, 20 + self.__r, fill="#AAAAAA", outline="#ffffff", tags="node", ) self.canvas.create_text(330, 20, text=u'Searched', fill='black' ) for i in range(self.width): for j in range(self.height): # 生成障礙節點,半徑為self.__r if test_map[j][i] == '#': node = self.canvas.create_oval(i * 10 + 50 - self.__r, j * 10 + 50 - self.__r, i * 10 + 50 + self.__r, j * 10 + 50 + self.__r, fill="#ff0000", # 填充紅色 outline="#ffffff", # 輪廓白色 tags="node", ) # 顯示起點 if test_map[j][i] == 'S': node = self.canvas.create_oval(i * 10 + 50 - self.__r, j * 10 + 50 - self.__r, i * 10 + 50 + self.__r, j * 10 + 50 + self.__r, fill="#00ff00", # 填充綠色 outline="#ffffff", # 輪廓白色 tags="node", ) self.canvas.create_text(i * 10 + 50, j * 10 + 50 - 20, # 使用create_text方法在坐標處繪制文字 text=u'Start', # 所繪制文字的內容 fill='black' # 所繪制文字的顏色為灰色 ) # 顯示終點 if test_map[j][i] == 'E': node = self.canvas.create_oval(i * 10 + 50 - self.__r, j * 10 + 50 - self.__r, i * 10 + 50 + self.__r, j * 10 + 50 + self.__r, fill="#00ff00", # 填充綠色 outline="#ffffff", # 輪廓白色 tags="node", ) self.canvas.create_text(i * 10 + 50, j * 10 + 50 + 20, # 使用create_text方法在坐標處繪制文字 text=u'End', # 所繪制文字的內容 fill='black' # 所繪制文字的顏色為灰色 ) # 生成路徑節點,半徑為self.__r if test_map[j][i] == '*': node = self.canvas.create_oval(i * 10 + 50 - self.__r, j * 10 + 50 - self.__r, i * 10 + 50 + self.__r, j * 10 + 50 + self.__r, fill="#0000ff", # 填充藍色 outline="#ffffff", # 輪廓白色 tags="node", ) # 生成搜索區域,半徑為self.__r if test_map[j][i] == ' ': node = self.canvas.create_oval(i * 10 + 50 - self.__r, j * 10 + 50 - self.__r, i * 10 + 50 + self.__r, j * 10 + 50 + self.__r, fill="#AAAAAA", # 填充白色 outline="#ffffff", # 輪廓白色 tags="node", ) # 查找路徑的入口函數 def find_path(self): # 構建開始節點 p = Node_Elem(None, self.s_x, self.s_y, 0.0) while True: # 擴展節點 self.extend_round(p) # 如果open表為空,則不存在路徑,返回 if not self.open: return # 取F值最小的節點 idx, p = self.get_best() # 到達終點,生成路徑,返回 if self.is_target(p): self.make_path(p) return # 把此節點加入close表,并從open表里刪除 self.close.append(p) del self.open[idx] # 生成路徑 def make_path(self, p): # 從結束點回溯到開始點,開始點的parent == None while p: self.path.append((p.x, p.y)) p = p.parent # 判斷是否為終點 def is_target(self, i): return i.x == self.e_x and i.y == self.e_y # 取F值最小的節點 def get_best(self): best = None bv = 10000000 # MAX值 bi = -1 for idx, i in enumerate(self.open): value = self.get_dist(i) if value < bv: best = i bv = value bi = idx return bi, best # 求距離 def get_dist(self, i): # F = G + H # G 為當前路徑長度,H為估計長度 return i.dist + math.sqrt((self.e_x - i.x) * (self.e_x - i.x)) + math.sqrt((self.e_y - i.y) * (self.e_y - i.y)) # 擴展節點 def extend_round(self, p): # 八個方向移動 xs = (-1, 0, 1, -1, 1, -1, 0, 1) ys = (-1, -1, -1, 0, 0, 1, 1, 1) # 上下左右四個方向移動 xs = (0, -1, 1, 0) ys = (-1, 0, 0, 1) for x, y in zip(xs, ys): new_x, new_y = x + p.x, y + p.y # 檢查位置是否合法 if not self.is_valid_coord(new_x, new_y): continue # 構造新的節點,計算距離 node = Node_Elem(p, new_x, new_y, p.dist + self.get_cost( p.x, p.y, new_x, new_y)) # 新節點在關閉列表,則忽略 if self.node_in_close(node): continue i = self.node_in_open(node) # 新節點在open表 if i != -1: # 當前路徑距離更短 if self.open[i].dist > node.dist: # 更新距離 self.open[i].parent = p self.open[i].dist = node.dist continue # 否則加入open表 self.open.append(node) # 移動距離,直走1.0,斜走1.4 def get_cost(self, x1, y1, x2, y2): if x1 == x2 or y1 == y2: return 1.0 return 1.4 # 檢查節點是否在close表 def node_in_close(self, node): for i in self.close: if node.x == i.x and node.y == i.y: return True return False # 檢查節點是否在open表,返回序號 def node_in_open(self, node): for i, n in enumerate(self.open): if node.x == n.x and node.y == n.y: return i return -1 # 判斷位置是否合法,超出邊界或者為阻礙 def is_valid_coord(self, x, y): if x < 0 or x >= self.width or y < 0 or y >= self.height: return False return test_map[y][x] != '#' # 搜尋過的位置 def get_searched(self): l = [] for i in self.open: l.append((i.x, i.y)) for i in self.close: l.append((i.x, i.y)) return l # 獲取起點坐標 def get_start_XY(): return get_symbol_XY('S') # 獲取終點坐標 def get_end_XY(): return get_symbol_XY('E') # 查找特定元素 def get_symbol_XY(s): for y, line in enumerate(test_map): try: x = line.index(s) except: continue else: break return x, y # 標記路徑位置 def mark_path(l): mark_symbol(l, '*') # 標記已搜索過的位置 def mark_searched(l): mark_symbol(l, ' ') # 標記函數 def mark_symbol(l, s): for x, y in l: test_map[y][x] = s # 標記起點和終點 def mark_start_end(s_x, s_y, e_x, e_y): test_map[s_y][s_x] = 'S' test_map[e_y][e_x] = 'E' # 將地圖字符串轉化為表 def tm_to_test_map(): for line in tm: test_map.append(list(line)) # 尋找路徑 def find_path(): s_x, s_y = get_start_XY() e_x, e_y = get_end_XY() # A*算法 a_star = A_Star(tkinter.Tk(), s_x, s_y, e_x, e_y) a_star.root.mainloop() a_star.find_path() searched = a_star.get_searched() path = a_star.path # 標記已搜索過的位置 mark_searched(searched) # 標記路徑位置 mark_path(path) # 標記起點和終點 mark_start_end(s_x, s_y, e_x, e_y) print(u"路徑長度:%d" % (len(path))) print(u"搜索過的區域:%d" % (len(searched))) a_star = A_Star(tkinter.Tk(), s_x, s_y, e_x, e_y) a_star.root.mainloop() #----------- 程序的入口處 ----------- if __name__ == '__main__': print (u""" -------------------------------------------------------- 程序:A*迷宮問題程序 作者:Gm 日期:2019-7-08 語言:Python 3.7 -------------------------------------------------------- """) # 載入地圖 tm_to_test_map() # 尋找路徑 find_path()
感謝你能夠認真閱讀完這篇文章,希望小編分享的“Python3 A*尋路算法的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。