婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > python實現A*尋路算法

python實現A*尋路算法

熱門標簽:打電話機器人營銷 聊城語音外呼系統 ai電銷機器人的優勢 地圖標注自己和別人標注區別 騰訊地圖標注沒法顯示 商家地圖標注海報 南陽打電話機器人 孝感營銷電話機器人效果怎么樣 海外網吧地圖標注注冊

A* 算法簡介

A* 算法需要維護兩個數據結構:OPEN 集和 CLOSED 集。OPEN 集包含所有已搜索到的待檢測節點。初始狀態,OPEN集僅包含一個元素:開始節點。CLOSED集包含已檢測的節點。初始狀態,CLOSED集為空。每個節點還包含一個指向父節點的指針,以確定追蹤關系。

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

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

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

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

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

關鍵代碼介紹

保存基本信息的地圖類

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

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

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

在map類中添加一個創建不能通過節點的函數,節點值為1表示不能移動到該節點。

	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類中添加一個顯示地圖的函數,可以看到,這邊只是簡單的打印出所有節點的值,值為0或1的意思上面已經說明,在后面顯示尋路算法結果時,會使用到值2,表示一條從開始節點到目標節點的路徑。

	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 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)

搜索到的節點類

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

class SearchEntry():
	def __init__(self, x, y, g_cost, f_cost=0, pre_entry=None):
		self.x = x
		self.y = y
		# cost move form start entry to this entry
		self.g_cost = g_cost
		self.f_cost = f_cost
		self.pre_entry = pre_entry
	
	def getPos(self):
		return (self.x, self.y)

算法主函數介紹

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

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] = location
	while True:
		location = getFastPosition(openlist)
		if location is None:
			# not found valid path
			print("can't find valid path")
			break;
		
		if location.x == dest.x and location.y == dest.y:
			break
		
		closedlist[location.getPos()] = location
		openlist.pop(location.getPos())
		addAdjacentPositions(map, location, dest, openlist, closedlist)
	
	#mark the found path at the map
	while location is not None:
		map.map[location.y][location.x] = 2
		location = location.pre_entry

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

	# find a least cost position in openlist, return None if openlist is empty
	def getFastPosition(openlist):
		fast = None
		for entry in openlist.values():
			if fast is None:
				fast = entry
			elif fast.f_cost > entry.f_cost:
				fast = entry
		return fast

addAdjacentPositions 函數對應算法主函數循環介紹中的嘗試添加節點n的所有鄰節點n'。

	# add available adjacent positions
	def addAdjacentPositions(map, location, dest, openlist, closedlist):
		poslist = getPositions(map, location)
		for pos in poslist:
			# if position is already in closedlist, do nothing
			if 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 openlist
					openlist[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 position
					findEntry.g_cost = g_cost
					findEntry.f_cost = g_cost + h_cost
					findEntry.pre_entry = location

getPositions 函數獲取到所有能夠移動的節點,這里提供了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 None
		return (x, y)
		
	def getPositions(map, location):
		# use four ways or eight ways to move
		offsets = [(-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 函數判斷節點是否在OPEN集 或CLOSED集中

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

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

	# imporve the heuristic distance more precisely in future
	def 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.4
		else:
			return 1

代碼的初始化

可以調整地圖的長度,寬度和不可移動節點的數目。
可以調整開始節點和目標節點的取值范圍。

WIDTH = 10
HEIGHT = 10
BLOCK_NUM = 15
map = 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()

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

完整代碼

使用python3.7編譯

from random import randint

class SearchEntry():
	def __init__(self, x, y, g_cost, f_cost=0, pre_entry=None):
		self.x = x
		self.y = y
		# cost move form start entry to this entry
		self.g_cost = g_cost
		self.f_cost = f_cost
		self.pre_entry = pre_entry
	
	def getPos(self):
		return (self.x, self.y)

class Map():
	def __init__(self, width, height):
		self.width = width
		self.height = height
		self.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] = 1
	
	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)

	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 None
		return (x, y)
		
	def getPositions(map, location):
		# use four ways or eight ways to move
		offsets = [(-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 future
	def 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.4
		else:
			return 1

	# check if the position is in list
	def isInList(list, pos):
		if pos in list:
			return list[pos]
		return None
	
	# add available adjacent positions
	def addAdjacentPositions(map, location, dest, openlist, closedlist):
		poslist = getPositions(map, location)
		for pos in poslist:
			# if position is already in closedlist, do nothing
			if 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 openlist
					openlist[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 position
					findEntry.g_cost = g_cost
					findEntry.f_cost = g_cost + h_cost
					findEntry.pre_entry = location
	
	# find a least cost position in openlist, return None if openlist is empty
	def getFastPosition(openlist):
		fast = None
		for entry in openlist.values():
			if fast is None:
				fast = entry
			elif fast.f_cost > entry.f_cost:
				fast = entry
		return fast

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

	
WIDTH = 10
HEIGHT = 10
BLOCK_NUM = 15
map = 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()

到此這篇關于python實現A*尋路算法的文章就介紹到這了,更多相關python A*尋路算法內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Python3 A*尋路算法實現方式
  • python實現Dijkstra靜態尋路算法
  • python 實現A*算法的示例代碼

標簽:南寧 六盤水 聊城 撫州 揚州 牡丹江 迪慶 楊凌

巨人網絡通訊聲明:本文標題《python實現A*尋路算法》,本文關鍵詞  python,實現,尋路,算法,python,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《python實現A*尋路算法》相關的同類信息!
  • 本頁收集關于python實現A*尋路算法的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    91日韩精品一区| 国产精品一区二区无线| 国产不卡免费视频| 欧美日韩国产另类不卡| 国产精品久久久久精k8 | 最新中文字幕一区二区三区| 国产在线不卡一卡二卡三卡四卡| 国产suv精品一区二区883| 欧美巨大另类极品videosbest | 91超碰这里只有精品国产| 亚洲欧洲成人av每日更新| 五月激情综合色| 久久99精品国产91久久来源| 92国产精品观看| 中文字幕中文在线不卡住| 成人手机电影网| 精品久久久久久久久久久久包黑料| 视频一区在线视频| 欧美日韩高清一区| 亚洲福利视频一区| 91国在线观看| 午夜精品久久久久影视| 欧美精品亚洲二区| 国产精品一区2区| 中文字幕中文字幕中文字幕亚洲无线| 91色九色蝌蚪| 国产在线麻豆精品观看| 91久久人澡人人添人人爽欧美| 欧美激情一区二区在线| 国产精品综合二区| 91精品国产欧美一区二区| 成人免费高清视频在线观看| 亚洲丝袜另类动漫二区| 欧美成人一区二区三区在线观看| 欧美日韩成人高清| 在线中文字幕一区二区| 久久不见久久见免费视频7| 日韩亚洲欧美综合| 成人美女视频在线观看18| 亚洲午夜羞羞片| 国产精品久久午夜| 在线观看国产一区二区| 激情综合一区二区三区| 亚洲黄网站在线观看| 中文字幕av在线一区二区三区| 日韩一级欧美一级| 欧美日韩视频在线第一区| 北条麻妃一区二区三区| 91精品国产综合久久久蜜臀图片| 91亚洲国产成人精品一区二三 | 久久久久亚洲综合| 午夜电影网一区| www.爱久久.com| 91视频www| 东方欧美亚洲色图在线| 亚洲综合偷拍欧美一区色| 亚洲欧美激情视频在线观看一区二区三区 | 日韩欧美你懂的| 欧美日韩aaa| 欧美一区二区三区啪啪| 欧美男男青年gay1069videost| 精品一区二区三区在线播放| 亚洲成在人线在线播放| 亚洲成人av免费| 日韩不卡免费视频| 久久99日本精品| 国产一区二区三区美女| 成人国产亚洲欧美成人综合网| 色综合天天综合给合国产| 91在线观看地址| 亚洲v中文字幕| 99久久国产免费看| 精品国产在天天线2019| 亚洲乱码国产乱码精品精可以看| 亚洲一区二区三区中文字幕在线| 久久国内精品自在自线400部| 色综合久久久久综合体桃花网| 欧美国产一区视频在线观看| 成人av集中营| 亚洲免费资源在线播放| 蜜桃在线一区二区三区| 成人一级视频在线观看| 欧美色成人综合| 一区视频在线播放| 人妖欧美一区二区| 欧美日韩精品欧美日韩精品一 | 91国在线观看| 国产91在线看| 亚洲成a人片在线观看中文| 国产福利91精品| 日本高清不卡视频| 欧美精品一区二区久久婷婷| 国产在线麻豆精品观看| 欧美国产精品中文字幕| 成人免费黄色在线| 一区二区成人在线视频| 久久人人超碰精品| 色美美综合视频| 亚洲精选视频在线| 欧美日韩在线三级| 亚洲国产日日夜夜| 欧美视频自拍偷拍| 日韩福利视频网| 亚洲欧美日韩国产综合在线| 91精品欧美久久久久久动漫 | 亚洲日本一区二区三区| 在线播放中文字幕一区| 国产激情视频一区二区三区欧美 | 91视频一区二区| 国产精品2024| 狠狠狠色丁香婷婷综合激情| 亚洲精品国产无天堂网2021 | 福利91精品一区二区三区| 亚洲主播在线播放| 亚洲精品午夜久久久| 日韩精品一区二区三区在线播放 | 亚洲麻豆国产自偷在线| 最新欧美精品一区二区三区| 久久综合999| 国产蜜臀97一区二区三区| 56国语精品自产拍在线观看| 色婷婷精品大在线视频| 99国产精品国产精品毛片| 99国产精品国产精品久久| 成人污视频在线观看| 成人综合婷婷国产精品久久蜜臀| 国产91丝袜在线播放0| 国产精品一线二线三线| 成人污污视频在线观看| jlzzjlzz欧美大全| 欧美图区在线视频| 欧美日韩一区 二区 三区 久久精品| 色综合欧美在线视频区| 欧美精品乱人伦久久久久久| 精品av综合导航| 亚洲mv在线观看| 免费久久99精品国产| 国产尤物一区二区在线| 成人福利视频在线看| 日本伦理一区二区| 久久久777精品电影网影网 | 久久精品国产99国产| 国产真实乱子伦精品视频| 99热99精品| 国产亚洲精品福利| 亚洲一区二区精品视频| 精品一区中文字幕| 国产麻豆视频一区二区| 色综合网色综合| 欧美国产一区二区| 中文字幕av一区二区三区高| 亚洲午夜成aⅴ人片| 国产在线一区二区综合免费视频| 欧美无乱码久久久免费午夜一区 | 亚洲1区2区3区4区| 一本到不卡精品视频在线观看| 国产亚洲欧美色| 99综合影院在线| 中文字幕不卡在线观看| 国产做a爰片久久毛片| 欧美成人aa大片| 亚洲女人****多毛耸耸8| 从欧美一区二区三区| 日韩欧美亚洲国产另类| 天天操天天色综合| 日韩一区二区免费电影| 国产一区二区三区蝌蚪| 欧美精品一区二区蜜臀亚洲| 麻豆专区一区二区三区四区五区| 欧美图区在线视频| 亚洲午夜视频在线| 欧美性高清videossexo| 亚洲一区二区三区小说| 欧美一区二区三区系列电影| 三级欧美在线一区| 欧美电视剧在线看免费| 国产一区二区三区四| 国产欧美日韩视频在线观看| 成人久久18免费网站麻豆| 亚洲bt欧美bt精品| 国产亚洲视频系列| 91精品国产欧美日韩| 美女脱光内衣内裤视频久久网站| 日韩欧美国产午夜精品| 国产成人日日夜夜| 日日摸夜夜添夜夜添精品视频| 欧美一区二区视频免费观看| 成人黄色网址在线观看| 日韩影院在线观看| 国产精品免费av| 日本一区二区免费在线| 欧美大片一区二区三区| 欧美性色黄大片| 91在线无精精品入口| 久久99精品久久久久久国产越南| 国产精品国产自产拍高清av| 精品国产乱码久久久久久免费| 在线精品视频一区二区三四 | 欧美色窝79yyyycom| 91久久一区二区|