python A星算法

  • 效果图
  • 上代码
  • 源码下载地址
  • 程序下载地址

效果图

(程序在cmd中打印所以有点闪屏!!!)

上代码

# -*- coding: utf-8 -*-
# @Date    : 2019-12-23 20:53:33
# @Author  : Flying Hu (1152598046@qq.com)
# @Link    : http://www.flyinghu.cn
# @name    : A星算法实现
# @Version : 0.1import os
import math
from random import randint
import time# 定义全局变量
gz_char = '█'  # 定义默认格子字符
fruit_char = '★'  # 定义果实显示字符
self_char = '●'  # 定义自身显示字符
wall_char = '◆'  # 定义墙壁显示字符# 全程使用上往下方向为x正方向  (二维列表行索引增加方向)
# 全程使用左往右方向为y正方向  (二维列表列索引增加方向)class Map2D(object):'''2D地图类'''def __init__(self, width=20, height=20):'''初始化Args:width   地图宽height   地图高'''self.width = widthself.height = heightself.char = gz_char  # 地图默认字符# 生成地图self.map = [[self.char for col in range(self.width)] for row in range(self.height)]# 生成地图周围墙self.wall = [[i, j] for j in [-1, self.width] for i in range(self.height)] + [[j, i] for j in [-1, self.height] for i in range(-1, self.width + 1)]def __getitem__(self, item):'''以键方式取值'''return self.map[item]def __setitem__(self, key, value):'''以键方式存值'''self.map[key] = valuedef show(self):'''在控制台打印当前地图'''for row in self.map:for c in row:# 使用控制台颜色控制, 区分if c == self_char:print('\033[1;35;44m' + c + '\033[0m', end='')elif c == wall_char:print('\033[0;36;41m' + c + '\033[0m', end='')elif c == fruit_char:print('\033[1;33;40m' + c + '\033[0m', end='')else:print('\033[0;37;41m' + c + '\033[0m', end='')print()# 重置地图, 重置后就不会留下运动轨迹# self.reload()def reload(self):'''重置地图'''self.map = [[self.char for col in range(self.width)] for row in range(self.height)]class AStar(object):'''实现A星算法'''class Node(object):'''节点类'''def __init__(self, x, y, parent_node=None):self.x = xself.y = yself.parent = parent_node  # 父节点# F = G + H# G = 从起点 A 移动到指定方格的移动代价# H = 从指定的方格移动到终点 B 的估算成本。试探法。 这里使用 Manhattan 方法估算Hself.G = 0self.H = 0def __init__(self, map2D):'''初始化'''self.map = map2Ddef MinF(self):'''从open_list中取出F最小的节点Returns:minF    返回open_list中F值最小的节点'''# 先假设第一个为最小, 然后循环挑选出F最小的节点minF = self.open_list[0]for node in self.open_list:if (node.G + node.H) <= (minF.G + minF.H):minF = nodereturn minFdef in_close_list(self, x, y):'''判断坐标是否在close_list中Args:x   x坐标y   y坐标Return:node    如果坐标在close_list中, 返回该节点, 反之返回False'''for node in self.close_list:if node.x == x and node.y == y:return nodereturn Falsedef in_open_list(self, x, y):'''判断坐标是否在open_list中Args:x   x坐标y   y坐标Return:node    如果坐标在open_list中, 返回该节点, 反之返回False'''for node in self.close_list:if node.x == x and node.y == y:return nodereturn Falsedef search(self, node):'''搜索周围路径Args:node 搜索节点'''# 判断改节点是否为障碍物(障碍物或者墙壁)if [node.x, node.y] in self.obstacles:# 如果为障碍物则忽略该路径return# 判断是否在close_list中if self.in_close_list(node.x, node.y):# 如果已经在close_list中则忽略该节点return# 计算G和Hnode.G = node.parent.G + 10node.H = abs(self.target_node.x - node.x) + \abs(self.target_node.y - node.y) * 10# 判断是否在open_list中tmp = self.in_close_list(node.x, node.y)if tmp:# 在open_list中# 比较当前F和open_list中Fif (node.G + node.H) < (tmp.G + tmp.H):# 如果判断该路径F值是否比open_list中存在的相同坐标的F值更小tmp = nodeelse:# 不在open_list中, 向open_list中添加self.open_list.append(node)def start(self, current_position, target_positiion, obstacles):'''计算A星最优路径Args:current_position    当前位置坐标target_positiion    目标位置坐标obstacles           障碍物坐标列表Returns:path_list           如果存在最优路径返回A星最优路径, 反正返回None'''# 目标节点self.target_node = AStar.Node(*target_positiion)# 当前节点self.current_node = AStar.Node(*current_position)# 开启表, 添加当前节点到open_list中self.open_list = [self.current_node]# 关闭表self.close_list = []# 障碍物坐标集  (真实障碍物 + 墙壁)self.obstacles = obstacles + self.map.wall# 开启A星计算循环while True:# 判断是否到达终点, 判断目标节点坐标是否在close_list中tmp = self.in_close_list(self.target_node.x, self.target_node.y)if tmp:# 返回路线path_list = [[tmp.x, tmp.y]]# 逆推路线while tmp.parent:tmp = tmp.parentpath_list.append([tmp.x, tmp.y])# 反转列表path_list.reverse()return path_listif not self.open_list:# 如果open_list为空, 表示无路可走return None# 从open_list中选出F最小路径节点minF = self.MinF()# 将当前选出节点添加到close_list中, 并从open_list中移除self.close_list.append(minF)self.open_list.remove(minF)# 搜索路径并将当前节点作为父节点  根据固定顺序搜索  (固定就行, 顺序任意)self.search(AStar.Node(minF.x - 1, minF.y, minF))self.search(AStar.Node(minF.x, minF.y - 1, minF))self.search(AStar.Node(minF.x + 1, minF.y, minF))self.search(AStar.Node(minF.x, minF.y + 1, minF))# 存在计算时长比较久的清空, 打印提示信息print('\r叼毛, 正在规划路径...', end='')def sub_start(self, current_position, target_positiion, obstacles, num=20):'''限定次数判断是否有路可走'''# 目标节点self.target_node = AStar.Node(*target_positiion)# 当前节点self.current_node = AStar.Node(*current_position)# 开启表, 添加当前节点到open_list中self.open_list = [self.current_node]# 关闭表self.close_list = []# 障碍物坐标集  (真实障碍物 + 墙壁)self.obstacles = obstacles + self.map.wall# 开启A星计算循环for i in range(num):# 判断是否到达终点, 判断目标节点坐标是否在close_list中tmp = self.in_close_list(self.target_node.x, self.target_node.y)if tmp:# 返回路线path_list = [[tmp.x, tmp.y]]# 逆推路线while tmp.parent:tmp = tmp.parentpath_list.append([tmp.x, tmp.y])# 反转列表path_list.reverse()return Trueif not self.open_list:# 如果open_list为空, 表示无路可走return False# 从open_list中选出F最小路径节点minF = self.MinF()# 将当前选出节点添加到close_list中, 并从open_list中移除self.close_list.append(minF)self.open_list.remove(minF)# 搜索路径并将当前节点作为父节点  根据固定顺序搜索  (固定就行, 顺序任意)self.search(AStar.Node(minF.x - 1, minF.y, minF))self.search(AStar.Node(minF.x, minF.y - 1, minF))self.search(AStar.Node(minF.x + 1, minF.y, minF))self.search(AStar.Node(minF.x, minF.y + 1, minF))else:return Trueclass Game(object):'''游戏类'''def __init__(self, map2D, obs_num=None):'''初始化Args:map2D   2D地图obs_num 初始化障碍物数量'''self.map = map2Dself.height = self.map.heightself.width = self.map.width# 随机一个初始化运动方向self.direction = randint(0, 3)# 根据地图大小计算障碍物数量# self.obs_num = int(math.sqrt(self.height * self.width))self.obs_num = obs_num if obs_num else int(math.sqrt(self.height * self.width))# 初始化起点self.current = [randint(int(1/4 * (self.height - 1)),int(3/4 * (self.height - 1))),randint(int(1/4 * (self.width - 1)),int(3/4 * (self.width - 1)))]# 生成果实目标self.gen_fruit()# 生成障碍物self.gen_obs()def gen_fruit(self):'''生成果实'''while True:# 随机生成果实坐标self.fruit = [randint(0, self.height - 1),randint(0, self.width - 1)]# 避免果实和起点坐标重合if self.fruit != self.current:breakdef gen_obs(self):'''生成障碍物'''self.obs_list = []for i in range(self.obs_num):while True:tmp = [randint(0, self.height - 1), randint(0, self.width - 1)]# 避免障碍物和起点或者果实重合if tmp != self.current and tmp != self.fruit:self.obs_list.append(tmp)breakdef move(self):'''根据移动方向移动0, 1, 2, 3分别对应上, 左, 下, 右'''if self.direction == 0:self.current = [self.current[0] - 1, self.current[1]]elif self.direction == 1:self.current = [self.current[0], self.current[1] - 1]elif self.direction == 2:self.current = [self.current[0] + 1, self.current[1]]else:self.current = [self.current[0], self.current[1] + 1]def cls(self):'''清空控制台输出'''os.system('cls')def load(self):'''加载果实和障碍物'''# 加载障碍物for row, col in self.obs_list:self.map[row][col] = wall_char# 加载果实和当前点row, col = self.currentself.map[row][col] = self_charrow, col = self.fruitself.map[row][col] = fruit_chardef start(self):'''开始游戏循环'''# 开启A星g = self.a_star()# 进入循环while True:# 清空控制台输出self.cls()# 加载self.load()# 打印显示self.map.show()# 判断是否吃到果实if self.current == self.fruit:# 吃到果实# 重置地图self.map.reload()# 重新生成果实, 重新生成障碍物self.gen_fruit()self.gen_obs()self.map.reload()if next(g) is False:# 表示无路可走# 重置地图self.map.reload()continue# 移动self.move()# 控制移动速度time.sleep(0.3)def a_star(self):'''接入A*算法寻路使用python生成器方式实现在游戏循环中一次一次改变方向'''# 创建对象a = AStar(self.map)while True:# 提前加载显示地图, 提前显示可以人工判断是否真的无路可走# 清空控制台输出self.cls()# 加载self.load()# 打印显示self.map.show()# 先反向判断, 在限定次数中是否得出无路可走, 添加改策略一定程度减少计算时间很长的正向计算if a.sub_start(self.fruit, self.current, self.obs_list, 30) is False:# 表示无路可走input('无路可走, 回车刷新地图')self.map.reload()self.gen_fruit()self.gen_obs()# 返回无路可走信号yield Falsecontinuepath_list = a.start(self.current, self.fruit, self.obs_list)if not path_list:# 表示无路可走# 提前加载显示地图, 提前显示可以人工判断是否真的无路可走# 清空控制台输出# self.cls()# # 加载# self.load()# # 打印显示# self.map.show()input('无路可走, 回车刷新地图')self.map.reload()self.gen_fruit()self.gen_obs()# 返回无路可走信号yield Falsecontinue# 遍历启动后路径, 对比得出行走方向for path in path_list[1:]:if path[0] > self.current[0]:self.direction = 2elif path[0] < self.current[0]:self.direction = 0elif path[1] > self.current[1]:self.direction = 3else:self.direction = 1yieldif __name__ == "__main__":# 初始化控制台大小os.system("mode con cols=80 lines=80")# 创建地图map2D = Map2D(width=20, height=20)# 新建游戏, 指定障碍物game = Game(map2D, 150)# 开启游戏game.start()

源码下载地址

点击下载源码–>https://download.csdn.net/download/flyinghu123/12047767

程序下载地址

A星.exe–>https://download.csdn.net/download/flyinghu123/12047636

python 实现A星算法相关推荐

  1. Astar、A星算法解决八数码问题--python实现

    一.问题描述 数码问题又称9宫问题,与游戏"华容道"类似.意在给定的3*3棋格的8个格子内分别放一个符号,符号之间互不相同,余下的一格为空格.并且通常把8个符号在棋格上的排列顺序称 ...

  2. 不到一百行python代码简单实现A星算法

    为了更好地理解A星算法,自己手撸了一段91行的代码来实现A星算法 可能代码风格不是很好,因为这也就是一上午写出来的,只是简单实现了A星 过两天准备好好改动一下代码使其更易读,再好好备注一下. #pyt ...

  3. 收藏 | 一文洞悉Python必备50种算法(附解析)

    来源:CSDN 本文约3800字,建议阅读10分钟. 本文整理了实践中广泛应用的算法,简单语句诠释每个算法的基本思想. 本文是一些机器人算法(特别是自动导航算法)的Python代码合集. 其主要特点有 ...

  4. A星算法(Java实现)

    2019独角兽企业重金招聘Python工程师标准>>> 一.适用场景 在一张地图中,绘制从起点移动到终点的最优路径,地图中会有障碍物,必须绕开障碍物. 二.算法思路 1. 回溯法得到 ...

  5. python50种算法_收藏 | 一文洞悉Python必备50种算法(附解析)

    本文是一些机器人算法(特别是自动导航算法)的Python代码合集. 其主要特点有以下三点:选择了在实践中广泛应用的算法:依赖最少:容易阅读,容易理解每个算法的基本思想.希望阅读本文后能对你有所帮助. ...

  6. 用python实现基本A*算法

    本文由恋花蝶发表于http://blog.csdn.net/lanphaday,可以在保证全文完整的前提下任意形式自由传播,但必须保留本声明,违反必究. 最近因为一个任务要用到A*算法,就用C++实现 ...

  7. python50种算法_一文洞悉Python必备50种算法

    本文是一些机器人算法(特别是自动导航算法)的Python代码合集. 其主要特点有以下三点:选择了在实践中广泛应用的算法:依赖最少:容易阅读,容易理解每个算法的基本思想.希望阅读本文后能对你有所帮助. ...

  8. 大数据基石python学习_资源 | 177G Python/机器学习/深度学习/算法/TensorFlow等视频,涵盖入门/中级/项目各阶段!...

    原标题:资源 | 177G Python/机器学习/深度学习/算法/TensorFlow等视频,涵盖入门/中级/项目各阶段! 这是一份比较全面的视频教程,基本上包括了市面上所有关于机器学习,统计学习, ...

  9. 协同过滤算法概述与python 实现协同过滤算法基于内容(usr-item,item-item)

    协调过滤推荐概述 协同过滤(Collaborative Filtering)作为推荐算法中最经典的类型,包括在线的协同和离线的过滤两部分.所谓在线协同,就是通过在线数据找到用户可能喜欢的物品,而离线过 ...

  10. python贝叶斯优化算法_【干货】手把手教你Python实现自动贝叶斯调整超参数

    [导读]机器学习中,调参是一项繁琐但至关重要的任务,因为它很大程度上影响了算法的性能.手动调参十分耗时,网格和随机搜索不需要人力,但需要很长的运行时间.因此,诞生了许多自动调整超参数的方法.贝叶斯优化 ...

最新文章

  1. 关于开源精神和抄袭问题
  2. Semaphore(信号量)
  3. linux和windows接口中文乱码_使用jmeter进行接口自动化实例
  4. csu 1757(贪心或者树状数组)
  5. Throwable、Error、Exception、RuntimeException 区别 联系
  6. PHP的mongo扩展版本过低导致无法查询
  7. 正则表达式: 正向预查和负向预查
  8. spotify音乐下载_使用Python和R对音乐进行聚类以在Spotify上创建播放列表。
  9. 1.4- 定时任务总结之九句箴言
  10. tensorflow 如何获取模型中想要的张量
  11. 产生随机小数_如果取到小数区间内的任一数字?
  12. [datatable]关于在DataTable中执行DataTable.Select(“条件“)返回DataTable的解决方法
  13. 二叉树遍历——深度优先遍历、广度优先遍历
  14. 黑马程序员传智播客python 协程greenlet gevent学习笔记
  15. usb驱动设备该设备无法启动 代码10
  16. JMH在性能测试中的使用
  17. 网页设计与制作 项目教程 项目1
  18. 【OTT】国内主要OTT平台背后的那些CDN服务商
  19. HDFS常用命令总结
  20. Ubuntu18.04 安装 网易云音乐 解决 打不开的问题

热门文章

  1. Web系统大规模并发-电商秒杀与抢购
  2. 学习《自己动手写网络爬虫》之记录1
  3. 电工模拟接线软件 app_电气工程师手机必备APP
  4. 计算机多媒体课件制作,多媒体课件制作软件
  5. 2019最新《网易云课堂C++开发工程师案例-网吧收银系统(MFC+ADO)》
  6. 全渠道数字化营销平台
  7. 【GlobalMapper精品教程】007:如何加载谷歌卫星影像?
  8. 皮尔森相关系数、皮尔逊相关系数(Pearson correlation coefficient)的存在性问题
  9. matplotlib-27 内嵌环形饼图
  10. 【开源】3串锂电池充放电保护板设计参考