面试中算法(A星寻路算法)

一、问题需求:

     迷宫寻路游戏中,有一些小怪物要攻击主角,现在希望你给这些小怪物加上聪 明的AI (Artificial Intelligence,人工智能),让它们可以自动绕过迷宫中的障碍物,寻找到主角的所在。

A星寻路算法 (A*search algorithm),是一种用于寻找有效路径的算法。

迷宫游戏的场景通常都是由小方格组成的。假设我们有一个6x7大小的迷宫

绿色的格子是起点红色的格子是终点,中间的3个紫色格子是一堵墙

A星寻路算法通过计算和量化行走的各个方向的代价,来选择最优路径。
公式:F = G + H
G:从起点走到当前格子的成本,也就是已经花费了多少步。

H:在不考虑障碍的情况下,从当前格子走到目标格子的距离,也就是离目标还有多远。

F:G和H的综合评估,也就是从起点到达当前格子,再从当前格子到达目标格子的总步数。

每个方格都标上了 F , G , H 的值,就像起点右边的方格那样,左上角是 F ,左下角是 G ,右下角是 H 。

二、操作步骤:

两个集合如下:

 open_list――可到达的格子

 close_list—―已到达的格子

第1轮寻路历程 

第1步:把起点放入open_list可到达格子的集合。 

open_list:grid(2,1)

close_list:

第2步:找出open_list中F值最小的方格作为当前方格。虽然我们没有直接计算起点方格的F值,但此时open_list中只有唯一的方格grid (2,1),把当前格子移出open_list,放入close_list。代表这个格子已到达并检查过了。

open_list:

close_list:grid(2,1)

 

第3步:找出当前方格(刚刚检查过的格子)上、下、左、右所有可到达的格子,看它们是否在open_list或close_list当中。如果不在,则将它们加入open_list,计算出相应的G、H、F值,并把当前格子作为它们的“父节点”。

我们需要一次又一次重复刚才的第 2步和第3步,直到找到终点为止。

第2轮寻路历程

第1步,找出open_list中F值最小的方格,即方格grid (2,2),将它作为当前方格,并把当前方格移出open_list,放入close_list。代表这个格子已到达并检查过了。

第2步,找出当前方格上、下、左、右所有可到达的格子,看它们是否在open_list或 close_list当中。如果不在,则将它们加入open_list,计算出相应的G、H、F值,并把当前格子作为它们的“父节点”。 为什么这一次open_list只增加了2个新格子呢?因为grid (2,3)是墙壁,自然不用考虑,而grid (2,1)在close_list中,说明已经检查过了,也不用考虑。

第3轮寻路历程

第1步,找出open_list中F值最小的方格。由于此时有多个方格的F值相等,任意选择一个即可,如将grid (2,3)作为当前方格,并把当前方格移出open_list,放入close_list。代表这个格子已到达并检查过了。

第2步,找出当前方格上、下、左、右所有可到达的格子,看它们是否在open_list当中。如果不在,则将它们加入open_list,计算出相应的G、H、F值,并把当前格子作为它们的“父节点”。

剩下的操作就是以前面的方式继续迭代,直到open_list中出现终点方格为止。

''''pip install colorama'''
from colorama import init, Fore, Back, Styledef a_star_search(start, end):# 初始化# 待访问的格子open_list = []# 已访问的格子close_list = []# 把起点加入open_listopen_list.append(start)# 主循环,每一轮检查一个当前方格节点while len(open_list) > 0:# 在open_list中查找 F值最小的节点作为当前方格节点current_grid = find_min_gird(open_list)# 当前方格节点从openList中移除open_list.remove(current_grid)# 当前方格节点进入 closeListclose_list.append(current_grid)# 找到所有邻近节点neighbors = find_neighbors(current_grid, open_list, close_list)for grid in neighbors:# 邻近节点不在openList中,标记父亲、G、H、F,并放入openListgrid.init_grid(current_grid, end)open_list.append(grid)# 如果终点在openList中,直接返回终点格子for grid in open_list:if (grid.x == end.x) and (grid.y == end.y):return grid# openList用尽,仍然找不到终点,说明终点不可到达,返回空return Nonedef find_min_gird(open_list=[]):# 找到openList中F值最小的节点return min(open_list, key=lambda x: x.f)def find_neighbors(grid, open_list=[], close_list=[]):grid_list = []# 上下左右四个方向if is_valid_grid(grid.x, grid.y-1, open_list, close_list):grid_list.append(Grid(grid.x, grid.y-1))if is_valid_grid(grid.x, grid.y+1, open_list, close_list):grid_list.append(Grid(grid.x, grid.y+1))if is_valid_grid(grid.x-1, grid.y, open_list, close_list):grid_list.append(Grid(grid.x-1, grid.y))if is_valid_grid(grid.x+1, grid.y, open_list, close_list):grid_list.append(Grid(grid.x+1, grid.y))return grid_listdef is_valid_grid(x, y, open_list=[], close_list=[]):# 是否超过边界if x < 0 or x >= len(MAZE) or y < 0 or y >= len(MAZE[0]):return False# 是否有障碍物if MAZE[x][y] == 1:return False# 是否已经在open_list中if contain_grid(open_list, x, y):return False# 是否已经在closeList中if contain_grid(close_list, x, y):return Falsereturn Truedef contain_grid(grids, x, y):for grid in grids:if (grid.x == x) and (grid.y == y):return Truereturn Falseclass Grid:def __init__(self, x, y):self.x = xself.y = yself.f = 0self.g = 0self.h = 0self.parent = Nonedef init_grid(self, parent, end):self.parent = parentself.g = parent.g + 1self.h = abs(self.x - end.x) + abs(self.y - end.y)self.f = self.g + self.h# 迷宫地图
MAZE = [[0, 0, 0, 0, 0, 0, 0],[0, 0, 0, 1, 0, 0, 0],[0, 0, 0, 1, 0, 0, 0],[0, 0, 0, 1, 0, 0, 0],[0, 0, 0, 0, 0, 0, 0]
]if __name__ == '__main__':# 设置起点和终点start_grid = Grid(2, 1)# end_grid = Grid(2, 5)end_grid = Grid(3, 4)# 搜索迷宫终点result_grid = a_star_search(start_grid, end_grid)# 回溯迷宫路径path = []while result_grid is not None:path.append(Grid(result_grid.x, result_grid.y))result_grid = result_grid.parent# 输出迷宫和路径,路径用星号表示for i in range(0, len(MAZE)):for j in range(0, len(MAZE[0])):if contain_grid(path, i, j):print(Fore.RED + "*, "+Fore.RESET, end='')else:print(str(MAZE[i][j]) + ", ", end='')print()

      

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/16122.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

json web token及JWT学习与探索

JSON Web Token&#xff08;缩写 JWT&#xff09;是目前最流行的跨域认证解决方案 作用&#xff1a; 主要是做鉴权用的登录之后存储用户信息 生成得token(令牌)如下 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiaWF0IjoxNjg3Njc0NDkyLCJleHAiOjE2ODc3NjA4OTJ9.Y6eFG…

1107 老鼠爱大米

solution 记录每组的最大值&#xff0c;并比较组间的最大值胖胖鼠~ #include<iostream> using namespace std; int main(){int n, m, ans, fat -1, x;scanf("%d%d", &n, &m);for(int i 0; i < n; i){ans -1;for(int j 0; j < m; j){scanf(…

【C/C++】Makefile文件的介绍与基本用法

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

【论文复现】LSTM长短记忆网络

LSTM 前言网络架构总线遗忘门记忆门记忆细胞输出门 模型定义单个LSTM神经元的定义LSTM层内结构的定义 模型训练模型评估代码细节LSTM层单元的首尾的处理配置Tensorflow的GPU版本 前言 LSTM作为经典模型&#xff0c;可以用来做语言模型&#xff0c;实现类似于语言模型的功能&am…

【Torch学习笔记】

作者&#xff1a;zjk 和 的区别是逐元素相乘&#xff0c;是矩阵相乘 cat stack 的区别 cat stack 是用于沿新维度将多个张量堆叠在一起的函数。它要求所有输入张量具有相同的形状&#xff0c;并在指定的新维度上进行堆叠。

【NumPy】关于numpy.mean()函数,看这一篇文章就够了

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

Android11热点启动和关闭

Android官方关于Wi-Fi Hotspot (Soft AP) 的文章&#xff1a;https://source.android.com/docs/core/connect/wifi-softap?hlzh-cn 在 Android 11 的WifiManager类中有一套系统 API 可以控制热点的开和关&#xff0c;代码如下&#xff1a; 开启热点&#xff1a; // SoftApC…

国际版Tiktok抖音运营流量实战班:账号定位/作品发布/热门推送/等等-13节

课程目录 1-tiktok账号定位 1.mp4 2-tiktok作品发布技巧 1.mp4 3-tiktok数据功能如何开通 1.mp4 4-tiktok热门视频推送机制 1.mp4 5-如何发现热门视频 1.mp4 6-如何发现热门音乐 1.mp4 7-如何寻找热门标签 1.mp4 8-如何寻找垂直热门视频 1.mp4 9-如何发现热门挑战赛 1…

【Python特征工程系列】一文教你使用PCA进行特征分析与降维(案例+源码)

这是我的第287篇原创文章。 一、引言 主成分分析&#xff08;Principal Component Analysis, PCA&#xff09;是一种常用的降维技术&#xff0c;它通过线性变换将原始特征转换为一组线性不相关的新特征&#xff0c;称为主成分&#xff0c;以便更好地表达数据的方差。 在特征重要…

DAMA数据管理知识体系必背18张框图

近期对数据管理知识体系中比较重要的框图进行了梳理总结,总共有18张框图,供大家参考。主要涉及数据管理、数据治理阶段模式、数据安全需求、主数据管理关键步骤,主数据架构、DW架构、数据科学的7个阶段、数据仓库建设活动、信息收敛三角、大数据分析架构图、数据管理成熟度等…

QGIS开发笔记(二):Windows安装版二次开发环境搭建(上):安装OSGeo4W运行依赖其Qt的基础环境Demo

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/139136356 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

Charles抓包App_https_夜神模拟器

Openssl安装 下载安装 下载地址&#xff1a; http://slproweb.com/products/Win32OpenSSL.html 我已经下载好了64位的&#xff0c;也放出来&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1Nkur475YK48_Ayq_vEm99w?pwdf4d7 提取码&#xff1a;f4d7 --来自百度网…

地下城游戏(leetcode)

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 地下城游戏https://leetcode.cn/problems/dungeon-game/description/ 图解分析&#xff1a; 代码 class Solution { public:int calculateMinimumHP(vector<vector<int>>& vv) {int row vv.size(), col …

Zookeeper 安装教程和使用指南

一、Zookeeper介绍 ZooKeeper 是 Apache 软件基金会的一个开源项目&#xff0c;主要基于 Java 语言实现。 Apache ZooKeeper 是一个开源的分布式应用程序协调服务&#xff0c;提供可靠的数据管理通知、数据同步、命名服务、分布式配置服务、分布式协调等服务。 关键特性 分布…

Nginx实战(安装部署、常用命令、反向代理、负载均衡、动静分离)

文章目录 1. nginx安装部署1.1 windows安装包1.2 linux-源码编译1.3 linux-docker安装 2. nginx介绍2.1 简介2.2 常用命令2.3 nginx运行原理2.3.1 mater和worker2.3.3 Nginx 的工作原理 2.4 nginx的基本配置文件2.4.1 location指令说明 3. nginx案例3.1 nginx-反向代理案例013.…

数据结构和算法|排序算法系列(三)|插入排序(三路排序函数std::sort)

首先需要你对排序算法的评价维度和一个理想排序算法应该是什么样的有一个基本的认知&#xff1a; 《Hello算法之排序算法》 主要内容来自&#xff1a;Hello算法11.4 插入排序 插入排序的整个过程与手动整理一副牌非常相似。 我们在未排序区间选择一个基准元素&#xff0c;将…

移动云以深度融合之服务,令“大”智慧贯穿云端

移动云助力大模型&#xff0c;开拓创新领未来。 云计算——AI模型的推动器。 当前人工智能技术发展的现状和趋势&#xff0c;以及中国在人工智能领域的发展策略和成就。确实&#xff0c;以 ChatGPT 为代表的大型语言模型在自然语言处理、文本生成、对话系统等领域取得了显著的…

项目管理:敏捷实践框架

一、初识敏捷 什么是敏捷(Agile)?敏捷是思维方式。 传统开发模型 央企,国企50%-60%需求分析。整体是由文档控制的过程管理。 传统软件开发面临的问题: 交付周期长:3-6个月甚至更长沟通效果差:文档化沟通不及时按时发布低:技术债增多无法发版团队士气弱:死亡行军不关注…

Vmware 17安装 CentOS9

前言 1、提前下载好需要的CentOS9镜像&#xff0c;下载地址&#xff0c;这里下载的是x86_64 2、提前安装好vmware 17&#xff0c;下载地址 &#xff0c;需要登录才能下载 安装 1、创建新的虚拟机 2、在弹出的界面中选择对应的类型&#xff0c;我这里选择自定义&#xff0c;点…

python command乱码怎么解决

python command乱码怎么解决&#xff1f;具体方法如下&#xff1a; 先引入import sys 再加一句&#xff1a;typesys.getfilesystemencoding() 然后在输出乱码的数据的后面加上“.decode(utf-8).encode(type)”。 比如输入“ss”乱码。 就写成print ss.decode(utf-8).encode(typ…