星表 python_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 = map_border[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.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) 

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

```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值