python3.6实现的A星算法

python3.6实现的A星算法A星算法原理:原理我就不再赘述,可以参考这篇博客https://blog.csdn.net/hitwhylz/article/details/23089415最近用js写了一遍,用的同样的算法,需要js代码的看这里:https://blog.csdn.net/qq_39687901/article/details/85697127代码实现:首先添加两个通用类…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

A星算法原理:

    原理我就不再赘述,可以参考这篇博客https://blog.csdn.net/hitwhylz/article/details/23089415

    最近用js写了一遍,用的同样的算法,需要js代码的看这里:https://blog.csdn.net/qq_39687901/article/details/85697127

代码实现:

    首先添加两个通用类Array2D和Point:

class Array2D:
    """
        说明:
            1.构造方法需要两个参数,即二维数组的宽和高
            2.成员变量w和h是二维数组的宽和高
            3.使用:‘对象[x][y]’可以直接取到相应的值
            4.数组的默认值都是0
    """
    def __init__(self,w,h):
        self.w=w
        self.h=h
        self.data=[]
        self.data=[[0 for y in range(h)] for x in range(w)]


    def showArray2D(self):
        for y in range(self.h):
            for x in range(self.w):
                print(self.data[x][y],end=' ')
            print("")

    def __getitem__(self, item):
        return self.data[item]

 

class Point:
    """
    表示一个点
    """
    def __init__(self,x,y):
        self.x=x;self.y=y

    def __eq__(self, other):
        if self.x==other.x and self.y==other.y:
            return True
        return False
    def __str__(self):
        return "x:"+str(self.x)+",y:"+str(self.y)

 

    Array2D是为了简化二维数组的创建,Point是为了表示一个点,并且重载等号运算符,可以判断两个Point坐标是否相等.

 

    AStar类:

    


class AStar:
    """
    AStar算法的Python3.x实现
    """

    class Node:  # 描述AStar算法中的节点数据
        def __init__(self, point, endPoint, g=0):
            self.point = point  # 自己的坐标
            self.father = None  # 父节点
            self.g = g  # g值,g值在用到的时候会重新算
            self.h = (abs(endPoint.x - point.x) + abs(endPoint.y - point.y)) * 10  # 计算h值

    def __init__(self, map2d, startPoint, endPoint, passTag=0):
        """
        构造AStar算法的启动条件
        :param map2d: Array2D类型的寻路数组
        :param startPoint: Point或二元组类型的寻路起点
        :param endPoint: Point或二元组类型的寻路终点
        :param passTag: int类型的可行走标记(若地图数据!=passTag即为障碍)
        """
        # 开启表
        self.openList = []
        # 关闭表
        self.closeList = []
        # 寻路地图
        self.map2d = map2d
        # 起点终点
        if isinstance(startPoint, Point) and isinstance(endPoint, Point):
            self.startPoint = startPoint
            self.endPoint = endPoint
        else:
            self.startPoint = Point(*startPoint)
            self.endPoint = Point(*endPoint)

        # 可行走标记
        self.passTag = passTag

    def getMinNode(self):
        """
        获得openlist中F值最小的节点
        :return: Node
        """
        currentNode = self.openList[0]
        for node in self.openList:
            if node.g + node.h < currentNode.g + currentNode.h:
                currentNode = node
        return currentNode

    def pointInCloseList(self, point):
        for node in self.closeList:
            if node.point == point:
                return True
        return False

    def pointInOpenList(self, point):
        for node in self.openList:
            if node.point == point:
                return node
        return None

    def endPointInCloseList(self):
        for node in self.openList:
            if node.point == self.endPoint:
                return node
        return None

    def searchNear(self, minF, offsetX, offsetY):
        """
        搜索节点周围的点
        :param minF:F值最小的节点
        :param offsetX:坐标偏移量
        :param offsetY:
        :return:
        """
        # 越界检测
        if minF.point.x + offsetX < 0 or minF.point.x + offsetX > self.map2d.w - 1 or minF.point.y + offsetY < 0 or minF.point.y + offsetY > self.map2d.h - 1:
            return
        # 如果是障碍,就忽略
        if self.map2d[minF.point.x + offsetX][minF.point.y + offsetY] != self.passTag:
            return
        # 如果在关闭表中,就忽略
        currentPoint = Point(minF.point.x + offsetX, minF.point.y + offsetY)
        if self.pointInCloseList(currentPoint):
            return
        # 设置单位花费
        if offsetX == 0 or offsetY == 0:
            step = 10
        else:
            step = 14
        # 如果不再openList中,就把它加入openlist
        currentNode = self.pointInOpenList(currentPoint)
        if not currentNode:
            currentNode = AStar.Node(currentPoint, self.endPoint, g=minF.g + step)
            currentNode.father = minF
            self.openList.append(currentNode)
            return
        # 如果在openList中,判断minF到当前点的G是否更小
        if minF.g + step < currentNode.g:  # 如果更小,就重新计算g值,并且改变father
            currentNode.g = minF.g + step
            currentNode.father = minF

    def start(self):
        """
        开始寻路
        :return: None或Point列表(路径)
        """
        # 判断寻路终点是否是障碍
        if self.map2d[self.endPoint.x][self.endPoint.y] != self.passTag:
            return None

        # 1.将起点放入开启列表
        startNode = AStar.Node(self.startPoint, self.endPoint)
        self.openList.append(startNode)
        # 2.主循环逻辑
        while True:
            # 找到F值最小的点
            minF = self.getMinNode()
            # 把这个点加入closeList中,并且在openList中删除它
            self.closeList.append(minF)
            self.openList.remove(minF)
            # 判断这个节点的上下左右节点
            self.searchNear(minF, 0, -1)
            self.searchNear(minF, 0, 1)
            self.searchNear(minF, -1, 0)
            self.searchNear(minF, 1, 0)
            # 判断是否终止
            point = self.endPointInCloseList()
            if point:  # 如果终点在关闭表中,就返回结果
                # print("关闭表中")
                cPoint = point
                pathList = []
                while True:
                    if cPoint.father:
                        pathList.append(cPoint.point)
                        cPoint = cPoint.father
                    else:
                        # print(pathList)
                        # print(list(reversed(pathList)))
                        # print(pathList.reverse())
                        return list(reversed(pathList))
            if len(self.openList) == 0:
                return None

 

    最后,进行代码测试:

    

 

if __name__ == '__main__':
    #创建一个10*10的地图
    map2d=Array2D(10,10)
    #设置障碍
    map2d[4][0]= 1
    map2d[4][1] = 1
    map2d[4][2] = 1
    map2d[4][3] = 1
    map2d[4][4] = 1
    map2d[4][5] = 1
    map2d[4][6] = 1
    #显示地图当前样子
    map2d.showArray2D()
    #创建AStar对象,并设置起点为0,0终点为9,0
    aStar=AStar(map2d,Point(0,0),Point(9,0))
    #开始寻路
    pathList=aStar.start()
    #遍历路径点,在map2d上以'8'显示
    for point in pathList:
        map2d[point.x][point.y]=8
        # print(point)
    print("----------------------")
    #再次显示地图
    map2d.showArray2D()

 

运行效果:

python3.6实现的A星算法

最近用这个A星算法在游戏里实际应用上了:

https://blog.csdn.net/qq_39687901/article/details/88554716

 

 

    

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/185071.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • HTML超链接使用代码

    HTML超链接使用代码HTML超链接(链接)HTML使用标签来设置超文本链接。在标签中使用了href属性来描述链接的地址。超链接可以是一个字,一个词,或者一组词,也可以是一幅图像,您可以点击这些内容来跳转到新的文档或者当前文档中的某个部分。当您把鼠标指针移动到网页中的某个链接上时,箭头会变为一只小手。默认情况下,链接将以以下形式出现在浏览器中:一个未访问过的链接显示为蓝色字体并带有下划线。访问过的链接显…

  • 一文带你了解Zookeeper基本概念、集群搭建、使用方法「建议收藏」

    本文图文并茂的描述了:zookeeper是什么,演示了Zookeeper集群如何搭建、Zookeeper常用命令的使用、如何查看Zookeeper日志;详细描述了Zookeeper数据模型、watch机制、ACL、集群选举机制。非常适合刚接触ZK的小伙伴哟,相信你读完之后,最基本也能描述出Zookeeper是个什么了。ZooKeeper一、ZooKeeper1、Zookeeper概述​ Zookeeper是一个分布式协调服务的开源框架。主要作用是为分布式系统提供协调服务,包括但不限于:分布式锁

  • 数据结构与算法栈的详解_数据结构怎么判断出栈的顺序

    数据结构与算法栈的详解_数据结构怎么判断出栈的顺序一、什么是栈栈(stack)是一种先进后出的有序列表,其中的元素只能在线性表的同一端进出,允许元素插入和删除的一端被称为栈顶(top),固定的另一端被称为栈底(button)。二、数组简单实现栈

  • 测试用例模板和例子_测试用例怎么写 实例

    测试用例模板和例子_测试用例怎么写 实例编写测试用例HttpRunnerv3.x支持三种测试用例格式pytest,YAML和JSON。官方强烈建议以pytest格式而不是以前的YAML/JSON格式编写和维护测试用例格式关系如下图所示

  • Android代码混淆官方实现方法「建议收藏」

    Android代码混淆官方实现方法「建议收藏」首先查看一下“project.properties”这个文件:#ThisfileisautomaticallygeneratedbyAndroidTools.#Donotmodifythisfile–YOURCHANGESWILLBEERASED!##ThisfilemustbecheckedinVersionContro

  • idea下载及汉化

    idea下载及汉化安装软件和汉化插件下载地址 链接:https://pan.baidu.com/s/1ftvTcFvx0ett7IQhU7Hltg 提取码:b43t 复制这段内容后打开百度网盘手机App,操作更方便哦 现在安装idea–>基本大家都会 汉化: 不是很建议使用汉化版本的.但是原界面对新手不是很友好,也有人说汉化后的界面有的按钮会报错,算了..开始正题吧 先把汉化文件夹…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号