“ 探索迷局:解密广度寻路算法 “

news2024/10/2 14:21:10

在这里插入图片描述

================================
专栏文章,自下而上
数据结构与算法——二叉搜索树
数据结构与算法——深度寻路算法
数据结构与算法——二叉树+实现表达式树
数据结构与算法——树(三指针描述一棵树)
数据结构与算法——栈和队列<也不过如此>
数据结构与算法——八大经典排序算法详解
数据结构与算法——有头无头循环链表详解
数据结构与算法——顺序表

================================
在这里插入图片描述

文章目录

      • 1、介绍
      • 2、思想
      • 3、定义及快捷
      • 4、创建四叉树节点
      • 5、判断能不能走
      • 6、准备工作
      • 7、寻路
        • A、标记走过
        • B、对预测点进行移动处理
        • C、能走的情况下怎么处理
        • D、切换层数
      • 8、效果展示
      • 9、综合代码
      • 10、总结


1、介绍

广度寻路算法是一种基于图的搜索算法,用于寻找两个节点之间的最短路径。它从起点开始展开搜索,并逐步向外扩展,直到找到目标节点或所有节点都被访问过。广度寻路算法使用队列作为辅助数据结构来实现搜索。当一个节点被访问时,将其所有的邻居节点加入队列中,并标记为已访问。从队列中取出的节点继续进行扩展搜索,直到队列为空或目标节点被找到为止。广度寻路算法的时间复杂度为O(V+E),其中V为节点数,E为边数。由于它逐层扩展搜索,因此能够找到最短路径,但会占用较多的空间。需要源代码的私信我~

深度寻路算法:1.循环试探,遇到死胡同回退 2.循环 简单 3.不一定能找到最佳路径 4.空旷地形 深度寻路

广度寻路算法:
1. 不需要回退
2. 一定能找到最短路径

2、思想

在这里插入图片描述

深度寻路就好比猴哥的毫毛一样,直接派四个小兵分别去上下左右四个方位寻找,到达下一个位置时,再派四个小兵出去寻找(当然如果有的方向是障碍物,那就不用派人去了),就这样一直下去,最后会找到终点的,而且是最短路径(后面会解释为什么)

可能有的同学会问了,那要怎么实现呐,每次都要派四个小兵,而且有的不是障碍物的要一直寻路下去,这个时候我们就想到了四叉树来实现,把起点放入根节点,一层就代表一步

有的同学又会问了,那如果一张地图有很多条路径,那广度寻路怎么会找到最短的那一条路径?

其实思想很简单,就是一找到终点就结束循环,从终点往上遍历,这条路径一定是最短路径——因为这条路径是最先结束循环,即最先找到终点

3、定义及快捷

在开始写之前我们先把准备工作写好,比如行和列的定义,最大孩子的数量,因为是试探4个方向,所以最大孩子的数量为4,且这里定义的是四叉树,存储当前层和下一层节点地址的数组大小,地图中路和障碍物的枚举,上下左右方向的枚举,还要定义一个点类型,以及四叉树类型,四叉树中需要定义结构体数组,因为有四个孩子,还有一个重要的是定义当前孩子的数量,因为不仅父亲要指向孩子,孩子也还要指向父亲,因为最后确定最佳路径,还要从终点往上遍历

//行列
#define ROWS 10
#define COLS 10
//最大孩子数量
#define CHILD_NUM 4
//临时数组的最大容量
#define BUFF_SIZE 100
//地图枚举
enum Mymap{road,wall};
//方向枚举
enum Mydirect{p_up,p_left,p_down,p_right};
//点
typedef struct Mypoint 
{
	int row, col;
}Mypoint;
//四叉树节点类型
typedef struct myThree 
{
	Mypoint			pos;
	struct myThree* partent;
	struct myThree* Child[CHILD_NUM];
	int				Curchild_Num;  
}myThree;
#define SIZE sizeof(myThree)

4、创建四叉树节点

这里先是直接用快捷的方式,把四叉树中都初始化为0,然后再赋值点的坐标

myThree* createThreeNode(Mypoint* pos)
{
	myThree* pNew = malloc(SIZE);
	assert(pNew);
	memset(pNew, 0, SIZE);
	pNew->pos.row = pos->row;
	pNew->pos.col = pos->col;
	return pNew;
}

5、判断能不能走

当前点越界,以及辅助地图上标记过的点,是墙都不能走

bool can_Walk(Mypoint* pos, bool map[ROWS][COLS], bool pathMap[ROWS][COLS])
{
	//越界
	if (pos->row < 0 || pos->row >= ROWS || pos->col < 0 || pos->col >= COLS) 		return false;
	//走过
	if (pathMap[pos->row][pos->col]) return false;
	//是墙
	if (map[pos->row][pos->col]) return false;
	return true;
}

6、准备工作

1、简单用数组实现一个二维地图,用于寻路

2、定义起点和终点

3、定义辅助地图,用于标记有没有走过

4、定义两个辅助数组,用来在当前层和下一层之间切换,这两个数组分别是用来存储当前层和下一层节点的地址

5、创建一棵树,起点成为树根,并且根节点还有独占一层

6、准备一个预测点

7、定义isFindend,用来判断是否找到终点,因为寻找的过程是多层循环,一个break结束不了循环,所以定义了一个标记

	//1 地图  1表示障碍  0表示路
	bool map[ROWS][COLS] = 
	{
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
		{ 1, 0, 1, 1, 0, 0, 0, 1, 1, 1 },
		{ 1, 0, 1, 1, 0, 1, 0, 1, 1, 1 },
		{ 1, 0, 1, 1, 0, 1, 0, 0, 0, 1 },
		{ 1, 0, 1, 1, 0, 1, 1, 0, 1, 1 },
		{ 1, 0, 0, 0, 0, 0, 0, 0, 1, 1 },
		{ 1, 0, 1, 1, 1, 1, 1, 0, 1, 1 },
		{ 1, 0, 1, 1, 0, 0, 0, 0, 0, 1 },
		{ 1, 0, 1, 0, 0, 1, 1, 1, 0, 1 },
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
	};

	//点--起点和终点
	Mypoint begPos = { 1,1 };
	Mypoint endPos = { 8,8 };

	//辅助地图
	bool pathMap[ROWS][COLS] = { 0 };

	//创建一颗树
	myThree* pRoot = NULL;
	//起点成为树根
	pRoot = createThreeNode(&begPos);

	//辅助数组
	//记录当前层节点的地址
	myThree* currentLayer[BUFF_SIZE] = { 0 };
	// 当前层节点的数量
	int currentLayerSize = 0;
	//记录下一层节点的地址
	myThree* nextLayer[BUFF_SIZE] = { 0 };
	//下一层节点的数量
	int nextLayerSize = 0;

	//树的根节点独占一层
	currentLayer[currentLayerSize++] = pRoot;
	
	//预测点
	Mypoint search;
	
	//标记是否走到终点
	bool isFindend = false;
	
	//准备一个临时变量
	myThree* temp_Node = NULL;

7、寻路

寻路的思想前面已经讲过了,我们一层一层的遍历(即一步一步的遍历),然后对每一步的四个方向进行处理

A、标记走过

处理之前,我们还要标记当前点已经走过并且要把当前的孩子数量清空

//标记走过
pathMap[currentLayer[i]->pos.row][currentLayer[i]->pos.col] = true;
//孩子数量清空
currentLayer[i]->Curchild_Num = 0;

B、对预测点进行移动处理

预测点就是当前的点,然后用switch进行处理

//预测点就是当前点
search.row = currentLayer[i]->pos.row;
search.col = currentLayer[i]->pos.col;
switch(j)
{
	case p_up:  search.row--;  break;
	case p_down:  search.row++;  break;
	case p_left:  search.col--;  break;
	case p_right:  search.col++;  break;
}

C、能走的情况下怎么处理

能走的情况下当前点就要成为预测点的父节点,预测点还要成为当前点的孩子,除此之外还要把预测点放入下一层数组中,因为它的身份是预测点,即为当前点的孩子,最后还要判断是否到达终点

//能走
if (can_Walk(&search,map,pathMap))
{
	//创建树节点
	temp_Node = createThreeNode(&search);
	//预测点成为当前点的孩子
	currentLayer[i]->Child[currentLayer[i]->Curchild_Num++] = temp_Node;
	//当前点成为预测点的父亲
	temp_Node->partent = currentLayer[i];
	//放入下一层数组中
	nextLayer[nextLayerSize++] = temp_Node;
	//判断是否到达终点
	if (temp_Node->pos.row==endPos.row&& temp_Node->pos.col == endPos.col)
	{
		isFindend = true;
		break;
	}
}

D、切换层数

如果下一层的数组为空,这时候已经遍历到最后一层了,直接退出,否则切换到下一层

//下一层为空
if (nextLayerSize == 0) break;
//切换到下一层中
for (int i = 0; i < nextLayerSize; i++)
{
	currentLayer[i] = nextLayer[i];
}
currentLayerSize = nextLayerSize;

8、效果展示

明显看出,这是一条最短路径

在这里插入图片描述

9、综合代码

需要源代码的私信我~

在这里插入图片描述

10、总结

总结:
深度适合大地图 开阔地形
例如 走迷宫 开宝箱
广度适合小地图
回合制游戏 走格子

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

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

相关文章

C++的智能指针

文章目录 1. 内存泄漏1.1 什么是内存泄漏1.2 内存泄漏分类 2. 为什么需要智能指针3. 智能指针的使用及原理3.1 RAII3.2 使用RAII思想设计的SmartPtr类3.3 让SmartPtr像指针一样3.3 SmartPtr的拷贝3.4 auto_ptr3.5 unique_ptr3.6 shared_ptr3.6.1 shared_ptr的循环引用3.6.2 wea…

MYSQL-数据库管理(上)

一、数据库概述 一、数据库基本概念 1.1 数据 1&#xff09; 描述事物的符号记录称为数据&#xff08;Data&#xff09;。数字、文字、图形、图像、声音、档案记录等 都是数据。 2&#xff09;数据是以“记录”的形式按照统一的格式进行存储的&#xff0c;而不是杂乱无章的。…

机器学习之分类决策树与回归决策树—基于python实现

大家好&#xff0c;我是带我去滑雪&#xff01; 本期为大家介绍决策树算法&#xff0c;它一种基学习器&#xff0c;广泛应用于集成学习&#xff0c;用于大幅度提高模型的预测准确率。决策树在分区域时&#xff0c;会考虑特征向量对响应变量的影响&#xff0c;且每次仅使用一个分…

vs编译生成动态库

说明 windows版本&#xff0c;vs2019 创建一个动态库 新建一c项目&#xff0c;创建一个dll类型项目。 在头文件中添加一个mylib.h文件&#xff1a; #pragma once#ifndef MYLIB_H #define MYLIB_Hextern "C" __declspec(dllexport) void Hello(); extern "C…

UG NX二次开发(C++)-建模-修改NXObject或者Feature的颜色(一)

文章目录 1、前言2、在UG NX中修改Feature的颜色操作3、采用NXOpen(C)实现3.1 创建修改特征的方法3.2 调用ModifyFeatureColor方法3.3 测试结果 1、前言 在UG NX中&#xff0c;改变NXObject和Feature的操作是不相同的&#xff0c;所以其二次开发的代码也不一样&#xff0c;我们…

优化问题的拉格朗日Lagrange对偶法原理

首先我们定义一般形式的求解x的优化问题&#xff1a; 表示优化的目标函数&#xff0c;上述为最小优化&#xff0c;实际上最大优化可以改写为的形式表示第i个不等式约束表示等式约束 1. Lagrange对偶问题 上述优化问题的拉格朗日Lagrange对偶法求解&#xff0c;是将上述带约束…

Baumer工业相机堡盟工业相机如何联合BGAPISDK和Halcon实现图像的直方图算法增强(C#)

Baumer工业相机堡盟工业相机如何联合BGAPISDK和Halcon实现图像的直方图算法增强&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机使用图像算法增加图像的技术背景Baumer工业相机通过BGAPI SDK联合Halcon使用直方图图像增强算法1.引用合适的类文件2.BGAPI SDK在图像回调…

车牌识别系统完整商用级别设计流程

简介 车牌识别&#xff08;License Plate Recognition&#xff09;是一种通过计算机视觉技术识别和提取车辆车牌上字符信息的技术。它在交通管理、智慧停车、安防监控等领域有着广泛的应用。 本项目将带完整的了解车牌识别系统设计思路&#xff0c;以及实现流程。 算法部分应…

图书管理系统【控制台+MySQL】(Java课设)

系统类型 控制台类型Mysql数据库存储数据 使用范围 适合作为Java课设&#xff01;&#xff01;&#xff01; 部署环境 jdk1.8Mysql8.0Idea或eclipsejdbc 运行效果 本系统源码地址&#xff1a;https://download.csdn.net/download/qq_50954361/87737294 更多系统资源库地…

机器学习 --- 绪论

第1关&#xff1a;什么是机器学习 任务描述 ​ 本关任务&#xff1a;根据本节课所学知识完成本关所设置的选择题。 相关知识 ​ 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 什么是机器学习。 什么是机器学习 ​ 相信大家一定都非常喜欢吃西…

【Python】【进阶篇】21、Django Admin数据表可视化

目录 21、Django Admin数据表可视化1. 创建超级用户2. 将Model注册到管理后台1)在admin.py文件中声明 3. django_admin_log数据表 21、Django Admin数据表可视化 在《Django Admin后台管理系统》介绍过 Django 的后台管理系统是为了方便站点管理人员对数据表进行操作。Django …

【Java面试八股文】数据库篇

导航&#xff1a; 【黑马Java笔记踩坑汇总】JavaSEJavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成在线MySQL高级篇设计模式牛客面试题 目录 请你说说MySQL索引,以及它们的好处和坏处 请你说说MySQL的索引是什么结构,为什么不用哈希表 请你说说数据库索引的底…

R语言 | 编写自己的函数

目录 一、正式编写程序 二、设计第一个函数 三、函数也是一个对象 四、程序代码的简化 五、return()函数的功能 六、省略函数的大括号 七、传递多个参数函数的应用 7.1 设计可传递2个参数的函数 7.2 函数参数的默认值 7.3 3点参数“…”的使用 八、函数也可以作为参数 …

《针灸》笔记(倪海厦先生人纪系列针灸篇)

程序员上了年纪&#xff0c;各种职业病就来了&#xff0c;人工智能成为好工具的同时&#xff0c;自己的时间也多了一些。 了解他才能判断他的真伪&#xff0c;没学过就认为中医是糟粕的&#xff0c;请划走。 学到什么记什么&#xff0c;线上线下齐下手&#xff0c;自用笔记&…

【Python基础入门学习】Python高级变量你了解多少?

认识高级变量 1. 列表 list1.1 列表的定义1.2 列表常用操作关键字、函数和方法 1.3 循环遍历1.4 列表嵌套1.5 应用场景 2. 元组 tuple2.1 元组的定义2.2 元组常用操作2.3 应用场景 3. 字典 dictionary3.1 字典的含义3.2 字典常用操作3.3 应用场景 4. 字符串 string4.1 字符串的…

基于PyQt5的图形化界面开发——模拟医院管理系统

基于PyQt5的图形化界面开发——模拟医院管理系统 0. 前言1. 需求分析2. 挂号界面的思路、UI界面代码及相应触发函数2.1 思路分析2.2 ui_guahao.py2.3 相应的触发函数代码 3. 就诊界面的思路、UI界面代码及相应触发函数3.1 思路分析3.2 ui_jiuzhen.py3.3 相关触发函数&#xff1…

如何制定专属于自己的个人目标

文章目录 前言一、自问自答二、制定目标的原则1.明确性2.衡量性3.可实现性4.相关性5.时限性 三、对目标进行计划1.5W2H1.做什么&#xff08;what to do it&#xff09;2.为什么做&#xff08;why to do it)3.何时做&#xff08;when to do it&#xff09;4.何地做&#xff08;w…

8b/10b编码方式(详细)总结附实例快速理解

目录 前言一、简介二、转换过程2.1 背景2.2 具体转换过程 三、其他相关链接1、PCI总线及发展历程总结2、PCIe物理层总结-PCIE专题知识&#xff08;一&#xff09;3、PCIe数据链路层图文总结-PCIe专题知识&#xff08;二&#xff09; 前言 本文主要通过图文方式介绍8b/10b编码&…

Hystrix线程池问题

背景&#xff1a;在一个以springcloud为基础架构的微服务项目中&#xff0c;活动期间并发量一大就会出现服务调用失败的问题。经定位发现&#xff0c;被调用服务中无对应的请求日志&#xff0c;继续通过日志查询确认是feign调用时出现服务降级&#xff0c;进入降级方法统一返回…

教会你制作自己的浏览器 —— 并将 ChatGPT 接入

前期回顾 分享24个强大的HTML属性 —— 建议每位前端工程师都应该掌握_0.活在风浪里的博客-CSDN博客2分享4个HTML5 属性&#xff0c;开发必备https://blog.csdn.net/m0_57904695/article/details/130465836?spm1001.2014.3001.5501 &#x1f44d; 本文专栏&#xff1a;开发…