日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

python實現(xiàn)A*尋路算法

瀏覽:114日期:2022-06-17 08:01:25
目錄A* 算法簡介關(guān)鍵代碼介紹保存基本信息的地圖類搜索到的節(jié)點類算法主函數(shù)介紹代碼的初始化完整代碼A* 算法簡介

A* 算法需要維護兩個數(shù)據(jù)結(jié)構(gòu):OPEN 集和 CLOSED 集。OPEN 集包含所有已搜索到的待檢測節(jié)點。初始狀態(tài),OPEN集僅包含一個元素:開始節(jié)點。CLOSED集包含已檢測的節(jié)點。初始狀態(tài),CLOSED集為空。每個節(jié)點還包含一個指向父節(jié)點的指針,以確定追蹤關(guān)系。

A* 算法會給每個搜索到的節(jié)點計算一個G+H 的和值F:

F = G + H G:是從開始節(jié)點到當前節(jié)點的移動量。假設開始節(jié)點到相鄰節(jié)點的移動量為1,該值會隨著離開始點越來越遠而增大。 H:是從當前節(jié)點到目標節(jié)點的移動量估算值。 如果允許向4鄰域的移動,使用曼哈頓距離。如果允許向8鄰域的移動,使用對角線距離。

算法有一個主循環(huán),重復下面步驟直到到達目標節(jié)點:1 每次從OPEN集中取一個最優(yōu)節(jié)點n(即F值最小的節(jié)點)來檢測。2 將節(jié)點n從OPEN集中移除,然后添加到CLOSED集中。3 如果n是目標節(jié)點,那么算法結(jié)束。4 否則嘗試添加節(jié)點n的所有鄰節(jié)點n’。

鄰節(jié)點在CLOSED集中,表示它已被檢測過,則無需再添加。 鄰節(jié)點在OPEN集中: 如果重新計算的G值比鄰節(jié)點保存的G值更小,則需要更新這個鄰節(jié)點的G值和F值,以及父節(jié)點;否則不做操作 否則將該鄰節(jié)點加入OPEN集,設置其父節(jié)點為n,并設置它的G值和F值。

有一點需要注意,如果開始節(jié)點到目標節(jié)點實際是不連通的,即無法從開始節(jié)點移動到目標節(jié)點,那算法在第1步判斷獲取到的節(jié)點n為空,就會退出

關(guān)鍵代碼介紹保存基本信息的地圖類

地圖類用于隨機生成一個供尋路算法工作的基礎(chǔ)地圖信息

先創(chuàng)建一個map類, 初始化參數(shù)設置地圖的長度和寬度,并設置保存地圖信息的二維數(shù)據(jù)map的值為0, 值為0表示能移動到該節(jié)點。

class Map():def __init__(self, width, height):self.width = widthself.height = heightself.map = [[0 for x in range(self.width)] for y in range(self.height)]

在map類中添加一個創(chuàng)建不能通過節(jié)點的函數(shù),節(jié)點值為1表示不能移動到該節(jié)點。

def createBlock(self, block_num):for i in range(block_num):x, y = (randint(0, self.width-1), randint(0, self.height-1))self.map[y][x] = 1

在map類中添加一個顯示地圖的函數(shù),可以看到,這邊只是簡單的打印出所有節(jié)點的值,值為0或1的意思上面已經(jīng)說明,在后面顯示尋路算法結(jié)果時,會使用到值2,表示一條從開始節(jié)點到目標節(jié)點的路徑。

def showMap(self):print('+' * (3 * self.width + 2))for row in self.map:s = ’+’for entry in row:s += ’ ’ + str(entry) + ’ ’s += ’+’print(s)print('+' * (3 * self.width + 2))

添加一個隨機獲取可移動節(jié)點的函數(shù)

def generatePos(self, rangeX, rangeY):x, y = (randint(rangeX[0], rangeX[1]), randint(rangeY[0], rangeY[1]))while self.map[y][x] == 1:x, y = (randint(rangeX[0], rangeX[1]), randint(rangeY[0], rangeY[1]))return (x , y)搜索到的節(jié)點類

每一個搜索到將到添加到OPEN集的節(jié)點,都會創(chuàng)建一個下面的節(jié)點類,保存有entry的位置信息(x,y),計算得到的G值和F值,和該節(jié)點的父節(jié)點(pre_entry)。

class SearchEntry():def __init__(self, x, y, g_cost, f_cost=0, pre_entry=None):self.x = xself.y = y# cost move form start entry to this entryself.g_cost = g_costself.f_cost = f_costself.pre_entry = pre_entrydef getPos(self):return (self.x, self.y)算法主函數(shù)介紹

下面就是上面算法主循環(huán)介紹的代碼實現(xiàn),OPEN集和CLOSED集的數(shù)據(jù)結(jié)構(gòu)使用了字典,在一般情況下,查找,添加和刪除節(jié)點的時間復雜度為O(1), 遍歷的時間復雜度為O(n), n為字典中對象數(shù)目。

def AStarSearch(map, source, dest):...openlist = {}closedlist = {}location = SearchEntry(source[0], source[1], 0.0)dest = SearchEntry(dest[0], dest[1], 0.0)openlist[source] = locationwhile True:location = getFastPosition(openlist)if location is None:# not found valid pathprint('can’t find valid path')break;if location.x == dest.x and location.y == dest.y:breakclosedlist[location.getPos()] = locationopenlist.pop(location.getPos())addAdjacentPositions(map, location, dest, openlist, closedlist)#mark the found path at the mapwhile location is not None:map.map[location.y][location.x] = 2location = location.pre_entry

我們按照算法主循環(huán)的實現(xiàn)來一個個講解用到的函數(shù)。下面函數(shù)就是從OPEN集中獲取一個F值最小的節(jié)點,如果OPEN集會空,則返回None。

# find a least cost position in openlist, return None if openlist is emptydef getFastPosition(openlist):fast = Nonefor entry in openlist.values():if fast is None:fast = entryelif fast.f_cost > entry.f_cost:fast = entryreturn fast

addAdjacentPositions 函數(shù)對應算法主函數(shù)循環(huán)介紹中的嘗試添加節(jié)點n的所有鄰節(jié)點n’。

# add available adjacent positionsdef addAdjacentPositions(map, location, dest, openlist, closedlist):poslist = getPositions(map, location)for pos in poslist:# if position is already in closedlist, do nothingif isInList(closedlist, pos) is None:findEntry = isInList(openlist, pos)h_cost = calHeuristic(pos, dest)g_cost = location.g_cost + getMoveCost(location, pos)if findEntry is None :# if position is not in openlist, add it to openlistopenlist[pos] = SearchEntry(pos[0], pos[1], g_cost, g_cost+h_cost, location)elif findEntry.g_cost > g_cost:# if position is in openlist and cost is larger than current one,# then update cost and previous positionfindEntry.g_cost = g_costfindEntry.f_cost = g_cost + h_costfindEntry.pre_entry = location

getPositions 函數(shù)獲取到所有能夠移動的節(jié)點,這里提供了2種移動的方式:

允許上,下,左,右 4鄰域的移動 允許上,下,左,右,左上,右上,左下,右下 8鄰域的移動

def getNewPosition(map, locatioin, offset):x,y = (location.x + offset[0], location.y + offset[1])if x < 0 or x >= map.width or y < 0 or y >= map.height or map.map[y][x] == 1:return Nonereturn (x, y)def getPositions(map, location):# use four ways or eight ways to moveoffsets = [(-1,0), (0, -1), (1, 0), (0, 1)]#offsets = [(-1,0), (0, -1), (1, 0), (0, 1), (-1,-1), (1, -1), (-1, 1), (1, 1)]poslist = []for offset in offsets:pos = getNewPosition(map, location, offset)if pos is not None:poslist.append(pos)return poslist

isInList 函數(shù)判斷節(jié)點是否在OPEN集 或CLOSED集中

# check if the position is in listdef isInList(list, pos):if pos in list:return list[pos]return None

calHeuristic 函數(shù)簡單得使用了曼哈頓距離,這個后續(xù)可以進行優(yōu)化。getMoveCost 函數(shù)根據(jù)是否是斜向移動來計算消耗(斜向就是2的開根號,約等于1.4)

# imporve the heuristic distance more precisely in futuredef calHeuristic(pos, dest):return abs(dest.x - pos[0]) + abs(dest.y - pos[1])def getMoveCost(location, pos):if location.x != pos[0] and location.y != pos[1]:return 1.4else:return 1代碼的初始化

可以調(diào)整地圖的長度,寬度和不可移動節(jié)點的數(shù)目。可以調(diào)整開始節(jié)點和目標節(jié)點的取值范圍。

WIDTH = 10HEIGHT = 10BLOCK_NUM = 15map = Map(WIDTH, HEIGHT)map.createBlock(BLOCK_NUM)map.showMap()source = map.generatePos((0,WIDTH//3),(0,HEIGHT//3))dest = map.generatePos((WIDTH//2,WIDTH-1),(HEIGHT//2,HEIGHT-1))print('source:', source)print('dest:', dest)AStarSearch(map, source, dest)map.showMap()

執(zhí)行的效果圖如下,第一個表示隨機生成的地圖,值為1的節(jié)點表示不能移動到該節(jié)點。第二個圖中值為2的節(jié)點表示找到的路徑。

python實現(xiàn)A*尋路算法

完整代碼

使用python3.7編譯

from random import randintclass SearchEntry():def __init__(self, x, y, g_cost, f_cost=0, pre_entry=None):self.x = xself.y = y# cost move form start entry to this entryself.g_cost = g_costself.f_cost = f_costself.pre_entry = pre_entrydef getPos(self):return (self.x, self.y)class Map():def __init__(self, width, height):self.width = widthself.height = heightself.map = [[0 for x in range(self.width)] for y in range(self.height)]def createBlock(self, block_num):for i in range(block_num):x, y = (randint(0, self.width-1), randint(0, self.height-1))self.map[y][x] = 1def generatePos(self, rangeX, rangeY):x, y = (randint(rangeX[0], rangeX[1]), randint(rangeY[0], rangeY[1]))while self.map[y][x] == 1:x, y = (randint(rangeX[0], rangeX[1]), randint(rangeY[0], rangeY[1]))return (x , y)def showMap(self):print('+' * (3 * self.width + 2))for row in self.map:s = ’+’for entry in row:s += ’ ’ + str(entry) + ’ ’s += ’+’print(s)print('+' * (3 * self.width + 2))def AStarSearch(map, source, dest):def getNewPosition(map, locatioin, offset):x,y = (location.x + offset[0], location.y + offset[1])if x < 0 or x >= map.width or y < 0 or y >= map.height or map.map[y][x] == 1:return Nonereturn (x, y)def getPositions(map, location):# use four ways or eight ways to moveoffsets = [(-1,0), (0, -1), (1, 0), (0, 1)]#offsets = [(-1,0), (0, -1), (1, 0), (0, 1), (-1,-1), (1, -1), (-1, 1), (1, 1)]poslist = []for offset in offsets:pos = getNewPosition(map, location, offset)if pos is not None:poslist.append(pos)return poslist# imporve the heuristic distance more precisely in futuredef calHeuristic(pos, dest):return abs(dest.x - pos[0]) + abs(dest.y - pos[1])def getMoveCost(location, pos):if location.x != pos[0] and location.y != pos[1]:return 1.4else:return 1# check if the position is in listdef isInList(list, pos):if pos in list:return list[pos]return None# add available adjacent positionsdef addAdjacentPositions(map, location, dest, openlist, closedlist):poslist = getPositions(map, location)for pos in poslist:# if position is already in closedlist, do nothingif isInList(closedlist, pos) is None:findEntry = isInList(openlist, pos)h_cost = calHeuristic(pos, dest)g_cost = location.g_cost + getMoveCost(location, pos)if findEntry is None :# if position is not in openlist, add it to openlistopenlist[pos] = SearchEntry(pos[0], pos[1], g_cost, g_cost+h_cost, location)elif findEntry.g_cost > g_cost:# if position is in openlist and cost is larger than current one,# then update cost and previous positionfindEntry.g_cost = g_costfindEntry.f_cost = g_cost + h_costfindEntry.pre_entry = location# find a least cost position in openlist, return None if openlist is emptydef getFastPosition(openlist):fast = Nonefor entry in openlist.values():if fast is None:fast = entryelif fast.f_cost > entry.f_cost:fast = entryreturn fastopenlist = {}closedlist = {}location = SearchEntry(source[0], source[1], 0.0)dest = SearchEntry(dest[0], dest[1], 0.0)openlist[source] = locationwhile True:location = getFastPosition(openlist)if location is None:# not found valid pathprint('can’t find valid path')break;if location.x == dest.x and location.y == dest.y:breakclosedlist[location.getPos()] = locationopenlist.pop(location.getPos())addAdjacentPositions(map, location, dest, openlist, closedlist)#mark the found path at the mapwhile location is not None:map.map[location.y][location.x] = 2location = location.pre_entryWIDTH = 10HEIGHT = 10BLOCK_NUM = 15map = Map(WIDTH, HEIGHT)map.createBlock(BLOCK_NUM)map.showMap()source = map.generatePos((0,WIDTH//3),(0,HEIGHT//3))dest = map.generatePos((WIDTH//2,WIDTH-1),(HEIGHT//2,HEIGHT-1))print('source:', source)print('dest:', dest)AStarSearch(map, source, dest)map.showMap()

到此這篇關(guān)于python實現(xiàn)A*尋路算法的文章就介紹到這了,更多相關(guān)python A*尋路算法內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標簽: Python 編程
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
新版的欧美在线视频| 国产亚洲一区二区三区啪| 亚洲a成人v| 91久久午夜| 丝袜a∨在线一区二区三区不卡| 激情综合网址| 不卡一区综合视频| 亚洲一区免费| 青青青免费在线视频| 日韩视频在线一区二区三区 | 国产免费播放一区二区| 国产三级一区| 日韩在线短视频| 久久精品免费一区二区三区 | 色老板在线视频一区二区| 日本精品不卡| 欧美网站在线| 日韩av三区| 老牛影视精品| 综合在线一区| 精品视频一区二区三区四区五区| 三级精品视频| 日韩视频1区| av资源中文在线| 日韩中文字幕区一区有砖一区 | 三级欧美在线一区| 牛牛精品成人免费视频| 国产综合色产| 国产欧美激情| 欧美日韩三区| 久久亚洲人体| 久久亚洲视频| 精品视频91| 尤物精品在线| 欧美激情亚洲| 国产精品美女久久久| 精品国产欧美日韩| 亚洲久草在线| 免费污视频在线一区| 日本不卡不码高清免费观看| 欧美13videosex性极品| 青草综合视频| 99国产精品视频免费观看一公开| 麻豆精品在线视频| 中文字幕乱码亚洲无线精品一区| 久久久精品五月天| 免费一区二区三区在线视频| 午夜在线观看免费一区| 日韩成人a**站| 国产日韩欧美在线播放不卡| 亚洲一区二区动漫| 欧洲在线一区| 国产成人久久| 国产精品欧美三级在线观看 | 久草精品视频| 四虎精品一区二区免费| 亚洲高清激情| 超碰超碰人人人人精品| 日韩高清欧美激情| 狠狠爱成人网| 激情综合自拍| 久久婷婷激情| 国产拍在线视频| 精品一区电影| 麻豆精品在线视频| 国产精品22p| 国产美女亚洲精品7777 | 欧美亚洲tv| 综合激情一区| 天堂av在线一区| 亚洲欧洲一区二区天堂久久| 99久久视频| 日韩欧美一区二区三区在线视频| 精品亚洲精品| 精品久久国产一区| 国产一区二区三区四区五区| 久久av偷拍| 久久爱www成人| 国产精品超碰| 久久99久久久精品欧美| 国产日韩视频在线| 欧美日韩一区二区国产| 日韩国产精品久久久久久亚洲| 色综合视频一区二区三区日韩 | 欧美极品中文字幕| 国产精品激情| 国产精品网站在线看| 国产视频一区二| 国产欧美另类| 久久国产精品免费精品3p| 午夜电影一区| 国产欧美91| 国产一区二区亚洲| 韩国精品主播一区二区在线观看 | 国产日韩亚洲欧美精品| 国产精品探花在线观看| 欧美国产日韩电影| 麻豆精品99| 国产在线观看91一区二区三区| 欧美日韩网址| 国产精品大片免费观看| 精品一区二区三区中文字幕视频| 精品久久福利| 久久婷婷亚洲| 水野朝阳av一区二区三区| 亚洲人www| 国产欧美二区| 日产精品一区二区| 亚洲成人一区| 日本一区二区中文字幕| 久久久久久亚洲精品美女| 日韩免费在线| 亚洲免费激情| 日韩av成人高清| 国产精品一区二区精品| 成人黄色av| 国产亚洲午夜| 久久国产视频网| 亚洲va中文在线播放免费| 亚洲深夜影院| 欧美日韩伊人| 午夜av成人| 日韩一区二区三区精品视频第3页 日韩一区二区三区免费视频 | 亚洲精品极品少妇16p| 久久福利影视| 欧美亚洲三区| 亚洲www免费| 亚洲精品少妇| 日韩综合在线| 久久国产精品久久w女人spa| 欧美精品三级在线| 久久久久中文| 日韩中文av| av综合电影网站| 亚洲精品免费观看| 97精品国产福利一区二区三区| 99在线精品免费视频九九视| 国产精品久一| 蜜桃一区二区三区| 国产一级成人av| 播放一区二区| 日韩国产在线观看一区| 成人自拍av| 久久精品 人人爱| 国产综合婷婷| 久久精品二区亚洲w码| 热久久免费视频| 综合日韩av| 日韩欧美中文字幕在线视频| 日韩欧美一区二区三区在线观看| 亚久久调教视频| 久久国产中文字幕| 欧美精品二区| 亚洲免费专区| 亚洲性视频h| 麻豆成人综合网| 亚洲三级精品| 亚洲二区三区不卡| 97精品国产一区二区三区 | 日韩av二区在线播放| 伊人久久大香线蕉av不卡| 国产精品xxx在线观看| 日韩一区二区久久| 成人福利视频| 久久这里只有精品一区二区| 一区二区日韩免费看| 999国产精品999久久久久久| 欧美自拍一区| 欧美日韩视频| 在线一区视频观看| 成人在线视频区| 国产一级成人av| 中文字幕av亚洲精品一部二部 | 国产成人精品一区二区三区免费| 日本一区免费网站| 午夜宅男久久久| 精品中文一区| 韩国三级一区| 国语对白精品一区二区| 国产精品亚洲综合久久| 欧美专区18| 在线日韩欧美| 亚洲精品国产嫩草在线观看 | a国产在线视频| 欧美国产另类| 日本天堂一区| 亚洲开心激情| 欧美资源在线| 亚洲欧美日韩国产一区二区| 亚洲欧洲午夜| 99国产精品久久久久久久 | 精品国产亚洲日本| 欧美一区影院| 日本少妇精品亚洲第一区| 亚欧洲精品视频在线观看| 在线精品一区| 亚洲精品在线二区| 亚洲人成精品久久久| 亚洲人成高清| 婷婷综合电影|