A*(A星)算法python实现
在春节放假前两天我偶然看到了A\*算法(A\*算法是一个启发式的地图寻路算法),感觉挺有意思。正好放假前也没有什么事情,就花了一个下午写出算法的骨架,节后又花了半天时间完善屏幕输出的细节并且调试完成。
该实现只是一时兴起的随手而作,没有考虑性能和扩展性等问题。正在学习A\*算法的朋友可以拿去随便折腾。
Email: wang.zhigang@hotmail.com
代码的运行效果如下:
```pytho
#!/usr/bin/python
# vim:set fileencoding=utf-8
# 在春节放假前两天我偶然看到了A*算法,感觉挺有意思。正好放假前
# 也没有什么事情,就花了一个下午写出算法的骨架,节后又花了半天
# 时间完善屏幕输出的细节并且调试完成。
# 该实现只是一时兴起的随手而作,没有考虑性能和扩展性等问题。正
# 在学习A*的朋友可以拿去随便折腾。
# email: wang.zhigang@hotmail.com
import sys
_2dmap = []
start = None
end = None
open_list = {}
close_list = {}
map_border = ()
class Node:
def __init__(this, father, x, y):
if x < 0 or x >= map_border[0] or y < 0 or y >= map_border[1]:
raise Exception("node position can't beyond the border!")
this.father = father
this.x = x
this.y = y
if father != None:
G2father = calc_G(father, this)
if not G2father:
raise Exception("father is not valid!")
this.G = G2father + father.G
this.H = calc_H(this, end)
this.F = this.G + this.H
else:
this.G = 0
this.H = 0
this.F = 0
def reset_father(this, father, new_G):
if father != None:
this.G = new_G
this.F = this.G + this.H
this.father = father
def calc_G(node1, node2):
x1 = abs(node1.x-node2.x)
y1 = abs(node1.y-node2.y)
if (x1== 1 and y1 == 0):
return 10 # same row
if (x1== 0 and y1 == 1):
return 10 # same col
if (x1== 1 and y1 == 1):
return 14 # cross
else:
return 0
def calc_H(cur, end):
return abs(end.x-cur.x) + abs(end.y-cur.y)
# NOTE 这个地方可能成为性能瓶颈
def min_F_node():
if len(open_list) == 0:
raise Exception("not exist path!")
_min = 9999999999999999
_k = (start.x, start.y)
for k,v in open_list.items():
if _min > v.F:
_min = v.F
_k = k
return open_list[_k]
# 把相邻节点加入open list, 如果发现终点说明找到了路径
def addAdjacentIntoOpen(node):
# 将该节点从开放列表移到关闭列表当中。
open_list.pop((node.x, node.y))
close_list[(node.x, node.y)] = node
_adjacent = []
# 相邻节点还没有注意边界的情况
try:
_adjacent.append(Node(node , node.x - 1 , node.y - 1))
except Exception,e:
pass
try:
_adjacent.append(Node(node , node.x , node.y - 1))
except Exception,e:
pass
try:
_adjacent.append(Node(node , node.x + 1 , node.y - 1))
except Exception,e:
pass
try:
_adjacent.append(Node(node , node.x + 1 , node.y))
except Exception,e:
pass
try:
_adjacent.append(Node(node , node.x + 1 , node.y + 1))
except Exception,e:
pass
try:
_adjacent.append(Node(node , node.x , node.y + 1))
except Exception,e:
pass
try:
_adjacent.append(Node(node , node.x - 1 , node.y + 1))
except Exception,e:
pass
try:
_adjacent.append(Node(node , node.x - 1 , node.y))
except Exception,e:
pass
for a in _adjacent:
if (a.x,a.y) == (end.x, end.y):
new_G = calc_G(a, node) + node.G
end.reset_father(node, new_G)
print "find path finish!"
return True
if (a.x,a.y) in close_list:
continue
if (a.x,a.y) not in open_list:
open_list[(a.x,a.y)] = a
else:
exist_node = open_list[(a.x,a.y)]
new_G = calc_G(a, node) + node.G
if new_G < exist_node.G:
exist_node.reset_father(node, new_G)
return False
def find_the_path(start, end):
open_list[(start.x, start.y)] = start
the_node = start
try:
while not addAdjacentIntoOpen(the_node):
the_node = min_F_node()
except Exception,e:
# path not exist
print e
return False
return True
#=======================================================================
def print_map():
print ' Y',
for i in xrange(len(_2dmap)):
print i,
print
print ' X'
row = 0
for l in _2dmap:
print '%3d'%row,' ',
row = row+1
for i in l:
print i,
print
def mark_path(node):
if node.father == None:
return
_2dmap[node.x][node.y] = '#'
mark_path(node.father)
def preset_map():
global start,end,map_border
_2dmap.append('S X . . . . . . . . . . . . . X . . . .'.split())
_2dmap.append('. X . . . . . . . . . . . . . X . . . .'.split())
_2dmap.append('. X . . . . . . . . . . . . . X . . . .'.split())
_2dmap.append('. . . . . . . . . . . . . . . X . . . .'.split())
_2dmap.append('. . . . . . . . . . . . . . . X . . . .'.split())
_2dmap.append('. . . . . . . . . . . . . . . . . . . .'.split())
_2dmap.append('. . . . . . . . . . . . . . . X X X X .'.split())
_2dmap.append('. . . . . . . . . . . . . . . X . . . .'.split())
_2dmap.append('. . . . . . . . . . . . . . . X . X X X'.split())
_2dmap.append('. . . . . . . . . . . . . . . X . X . .'.split())
_2dmap.append('. . . . . . . . . . . . . . . X . . . .'.split())
_2dmap.append('. . . . . . . . . . . . . . . X . X . .'.split())
_2dmap.append('. . . . . . . . . . . . . . . X . X . .'.split())
_2dmap.append('. . . . . . . . . . . . . . . X . X . .'.split())
_2dmap.append('. . . . . . . . . . . . . . . X . X . .'.split())
_2dmap.append('. . . . . . . . . . . . . . . X . X . E'.split())
map_border = (len(_2dmap),len(_2dmap[0]))
row_index = 0
for row in _2dmap:
col_index = 0
for n in row:
if n == 'X':
block_node = Node(None, row_index, col_index)
close_list[(block_node.x, block_node.y)] = block_node
elif n == 'S':
start = Node(None, row_index, col_index)
elif n == 'E':
end = Node(None, row_index, col_index)
col_index = col_index + 1
row_index = row_index + 1
if __name__=='__main__':
if len(sys.argv) < 3:
preset_map()
else:
x = int(sys.argv[1])
y = int(sys.argv[2])
map_border = (x,y)
_start = raw_input('pls input start point:')
_end = raw_input('pls input end point:')
_start = _start.split(',')
_end = _end.split(',')
_start = (int(_start[0]), int(_start[1]))
_end = (int(_end[0]), int(_end[1]))
start = Node(None, _start[0], _start[1])
end = Node(None, _end[0], _end[1])
# gen map
_2dmap = [['.' for i in xrange(y)] for i in xrange(x) ]
# put start and end
_2dmap[_start[0]][_start[1]] = 'S'
_2dmap[_end[0]][_end[1]] = 'E'
# input blocks
while True:
_block = raw_input('input block:')
if not _block:
break
_block = _block.split(',')
_block = (int(_block[0]), int(_block[1]))
_2dmap[_block[0]][_block[1]] = 'X'
block_node = Node(None, _block[0], _block[1])
close_list[(block_node.x, block_node.y)] = block_node
print "orignal map:"
print_map()
if find_the_path(start, end):
mark_path(end.father)
print "found road as follow:"
print_map()
```
A*(A星)算法python实现的更多相关文章
- POJ 2449 Remmarguts' Date (SPFA + A星算法) - from lanshui_Yang
题目大意:给你一个有向图,并给你三个数s.t 和 k ,让你求从点 s 到 点 t 的第 k 短的路径.如果第 k 短路不存在,则输出“-1” ,否则,输出第 k 短路的长度. 解题思路:这道题是一道 ...
- 算法起步之A星算法
原文:算法起步之A星算法 用途: 寻找最短路径,优于bfs跟dfs 描述: 基本描述是,在深度优先搜索的基础上,增加了一个启发式算法,在选择节点的过程中,不是盲目选择,而是有目的的选的,F=G+H,f ...
- Cocos2d-x 3.1.1 学习日志16--A星算法(A*搜索算法)学问
A *搜索算法称为A星算法.这是一个在图形平面,路径.求出最低通过成本的算法. 经常使用于游戏中的NPC的移动计算,或线上游戏的BOT的移动计算上. 首先:1.在Map地图中任取2个点,開始点和结束点 ...
- A*搜寻算法(A星算法)
A*搜寻算法[编辑] 维基百科,自由的百科全书 本条目需要补充更多来源.(2015年6月30日) 请协助添加多方面可靠来源以改善这篇条目,无法查证的内容可能会被提出异议而移除. A*搜索算法,俗称A星 ...
- pageRank算法 python实现
一.什么是pagerank PageRank的Page可是认为是网页,表示网页排名,也可以认为是Larry Page(google 产品经理),因为他是这个算法的发明者之一,还是google CEO( ...
- 常见排序算法-Python实现
常见排序算法-Python实现 python 排序 算法 1.二分法 python 32行 right = length- : ] ): test_list = [,,,,,, ...
- kmp算法python实现
kmp算法python实现 kmp算法 kmp算法用于字符串的模式匹配,也就是找到模式字符串在目标字符串的第一次出现的位置比如abababc那么bab在其位置1处,bc在其位置5处我们首先想到的最简单 ...
- Java开源-astar:A 星算法
astar A星算法Java实现 一.适用场景 在一张地图中,绘制从起点移动到终点的最优路径,地图中会有障碍物,必须绕开障碍物. 二.算法思路 1. 回溯法得到路径 (如果有路径)采用“结点与结点的父 ...
- KMP算法-Python版
KMP算法-Python版 传统法: 从左到右一个个匹配,如果这个过程中有某个字符不匹配,就跳回去,将模式串向右移动一位.这有什么难的? 我们可以 ...
- A星算法(Java实现)
一.适用场景 在一张地图中.绘制从起点移动到终点的最优路径,地图中会有障碍物.必须绕开障碍物. 二.算法思路 1. 回溯法得到路径 (假设有路径)採用"结点与结点的父节点"的关系从 ...
随机推荐
- IIS 7.5 配置Asp+Access的几点注意的地方
环境:window2008 R2 + iis 7.51 把网站程序放在一个www文件夹里面,给这个文件夹添加everyone的用户,赋予全部读写权限,这样安全些.2 选中要配置的网站,点击页面中间“A ...
- java高级工程师必备知识
成为Java高级工程师需要掌握哪些核心点? 每 逢长假都会有很多程序员跳槽,十一.过年是跳槽黄金时刻,尤其是过年.过年的时候年终奖到手,没有了多少牵挂,年终同学同事聚会比较多,沟通的就多,各种 工作机 ...
- c#生成随机数示例分享
c#生成(随机数 http://www.jbxue.com/tags/suijishu.html)的代码. /// 构造随机数 种子 ]; System.Security.Cr ...
- public void onItemClick(AdapterView arg0, View view, int position,long arg3)详解【整理自网络】
参考自: http://blog.csdn.net/zwq1457/article/details/8282717 http://blog.iamzsx.me/show.html?id=147001 ...
- 使用WIF实现单点登录Part I——Windows Identity Foundation介绍及环境搭建
首先先说一下什么是WIF(Windows Identity Foundation).由于各种历史原因,身份验证和标识的管理一般都比较无规律可循.在软件里加入“身份验证”功能意味着要在你的代码里混进处理 ...
- NLP自然语言处理学习笔记三(集成开发环境)
前言: 我们在做自然语言学习的过程中使用Python进行编程.是用解析器的方式确实有些麻烦.在这里给大家推荐一款集成开发环境IDE可以很方便的对Python进行项目管理,代码自动提示,运行调试等. 简 ...
- salt-ssh安装及简单使用
需要 salt-master 0.17以上版本支持 1.安装 相关依赖包可查看requirements.txt Jinja2 M2Crypto msgpack-python pycrypto PyYA ...
- SQL1092N The requested command or operation failed because the user ID does not have the authority to perform the requested command or operation.
1.前一天安装号db2后,做了如下处理: ************************************************************ 修改 /etc/sudoers 文件 ...
- Redbean:入门(一) - 增删改查
<?php require_once 'rb.php'; $tableName = "link"; //链接数据库 R::setup("mysql:host=loc ...
- 6.24AppCan移动开发者大会价值30万的展示机会归了谁?
最近,小编的邮箱都被挤爆了! 来自开发者的邮件一封封涌进邮箱,VIP展位申请,TOP30 APP评选,感谢大家的积极参与,展位有限,APP名额有限,开发者的热情无限. 经过谨慎筛选.综合评定后,以下5 ...