找到距离集合Q最近的点B,将其加入集合Q中,并从P中删除,遍历与B相邻的点。由数组N可知A->B=5,B->D=5,所以A->B+B->D = 10,小于原本A->D的距离20,所以更新数组N。 说到游戏编程,寻路算法是许多RPG游戏无法避免的一个关键点,所以这一系列的文章就从本科最熟悉的Dijkstra算法开始讲起一步步到游戏中常用的A*算法。做一个简单的算法演示。

一、算法简介

Dijkstra算法是用来解决单源最短路径的算法,即在一个图中找出一个点N,找出以该点为起点到其他所有点的最短路径。但是如果想找到两个顶点A和C之间的最短路径时,Dijkstra算法可能同时找到到达其它顶点(例如顶点B)的最短路径,这一点将在算法演示的时候详细解释。同时Dijkstra算法无法适用于含有负权重的图。

算法的步骤如下:

1、维护一个数组N,两个集合P,Q,数组N用来储存起点到各个顶点的最短距离,集合P用来存储未遍历的点,集合Q存储已遍历的点。

2、选择起点,将起点添加到Q集合中,并从P集合中删除。将与起点相邻的点的距离添加到数组中,到不相邻点的距离用无穷大表示。

3、选择距离Q集合最近的一个点M(即与所有已遍历点相连的未遍历点中,边的权值最小的点)。将该点加入Q集合,并从P集合中删除。

4、找到与M相邻的点C,计算数组N中存储的到达C点的距离是否小于起点经过M到达C点的距离,若是,则更新N,否则继续寻找下一个与M相邻的点,重复步骤4直到遍历完M的所有邻点。

5、重复步骤3,4直至遍历集合P为空。

文字版看不明白没关系,接下来将有图示,可以直接看图示。

二、算法演示

下面将以点A使用Dijkstra算法:

假设以A为起点寻找最短路径,则维护一个数组N[5]={∞,∞,∞,∞,∞},存储A到点A,B,C,D,E的距离,同时维护集合P={A,B,C,D,E},集合Q={}
首先将点A加入集合Q,并从集合P中删除,更新数组N。因为与A相邻的点为B,C,D,所以此次循环更新到B,C,D的最短距离。
找到距离集合Q最近的点C,将其加入集合Q,并从集合P中删除,遍历与C相邻的点。由数组N我们可知A->C=3,所以A->C + C->B = 5,小于原数组中A->B的距离10,所以更新N。同样的A->C+C->E=18,小于无穷大,所以更新数组N。

找到距离集合Q最近的点B,将其加入集合Q中,并从P中删除,遍历与B相邻的点。由数组N可知A->B=5,B->D=5,所以A->B+B->D = 10,小于原本A->D的距离20,所以更新数组N。

找到距离集合Q最近的D,并将其加入集合Q中,并从P中删除,遍历与D相邻的点。我们发现A->D+D->E=21,大于原本A->E的距离18,所以不做处理。

找到距离集合Q最近的E,将其加入集合Q中,并从P中删除,遍历与E相邻的点。我们发现不存在与E相邻并可以到达的点,所以不做处理。至此最短路径便全部获得。

总结:我们可以发现,Dijkstra算法发现最短路径的方式并不是目的明确的,在上述例子中,我们发现最短路径的发现顺序依次是C,B,E,D 。所以当我们需要寻找点D的最短路径时会先找到起点到其他所有点的最短路径。与之相对应的A*算法寻找目标点则十分明确,关于A*我们将在往后的文章中提到。

三、局限性

Dijkstra算法是无法用于负权重的图的,这里只需要对上述例子修改一下,然后使用Dijkstra算法自行推算一遍就可以明白,当做一个简单的思考,下一篇讲Bellman-Ford算法的时候我会详细解释该图。

四、在游戏开发中的运用

很明显Dijkstra算法是不可能用于类似dota或者网页上常见的是兄弟就来砍我这些游戏的寻路,因为在找到对应目标前需要遍历其他不必要的点实在太多,这是一种浪费效率的做法,大多数这类游戏采用的都是A*算法。

Dijkstra算法适用的场景是类似于文明6这种战棋游戏(当然我也只是说适用,天知道文明6用的是哪种算法)。因为战棋游戏每一个棋子移动到某个网格的消耗都必须在玩家选中该棋子时实时呈现给玩家,所以遍历棋子周围的网格是一种很有必要的做法,因为电脑并不清楚玩家到底会选择向哪个方向移动。如下图,我们显然可以发现一个棋子移动前,所有可到达地点都已经被标记好了,很明显这是一种遍历后才能出现的结果。

两者的区别就这样体现出来了:前者的移动是先输入具体位置,然后由计算机计算该怎么移动。而后者是先告诉玩家可移动范围,再由玩家输入具体要去的位置。

这里是阿松,如有错漏,恳请指正。这里是我的微信公众号游程指北,你小小的关注就是对我最大的帮助,感谢大家。

最短路径问题(1)——Dijkstra算法​mp.weixin.qq.com

网上路径的图片有时候遍历不出来_最短路径问题(1)——Dijkstra算法相关推荐

  1. java dijkstra算法代码_[转载]Java实现dijkstra算法: 地图中任意起点寻找最佳路径...

    最近在复习java,下学期要用,写这个练手.  技术较粗糙,见谅. 代码里用的是这幅地图,根据实际情况更改,在addNode方法中 这个是运行结果,起点和终点在 运行wrap(String qidia ...

  2. 牛客网 短最优升级路径 【Dijkstra算法】+【路径记录】

    链接:https://www.nowcoder.com/questionTerminal/a7052c5bd8634edb9ccee711a5c1ea54 来源:牛客网 短最优升级路径 题目描述:游戏 ...

  3. java dijkstra算法 指定源宿_一种路径计算的方法和装置与流程

    本发明涉及网络通信技术,尤其涉及一种路径计算的方法和装置. 背景技术: 随着软件定义网络(Software Defined Network,SDN).网络功能虚拟化(Network Function ...

  4. 【转】mysql保存图片技术决定:保存二进制文件还是只保存图片相对路径,图片放在硬盘上面?...

    最近遇到上面这个问题,一开始我就果断否决了数据库保存图片的策略,主要是太蠢!事实上我的决定是正确的,我仅仅理解为mysql读写性能提高的境界,具体为什么可以提高?很模糊,知道我看到了这里: 大佬做的实 ...

  5. access找不到输入表或者dual_在Access窗体中显示指定路径的图片

    ↑↑↑点击上方图片,了解详情 在Access中,如果把图形对象以OLE格式的字段保存,那么在窗体中可以直接显示出图片来.但是这样做有以下不足: 一.需要将图片逐一插入到表中,工作量太大. 二.使数据库 ...

  6. android怎么让图片显示在button上面_网上的图片不知道怎么批量下载?python教你怎么把网站上面的图片都爬下来...

    ## **妹子图网站----前言** 从今天开始就要撸起袖子,直接写Python爬虫了,学习语言最好的办法就是有目的的进行,所以,接下来我将用10+篇的博客,写`爬图片`这一件事情.希望可以做好. 为 ...

  7. 在access窗体中加图片_如何在Access窗体中显示指定路径的图片

    在Access中,如果把图形对象以OLE格式的字段保存,那么在窗体中可以直接显示出图片来.但是这样做有以下不足:一.需要将图片逐一插入到表中,工作量太大.二.使数据库文件变得庞大.三.相同的图片文件, ...

  8. Python语言学习:利用python获取当前/上级/上上级目录路径(获取路径下的最后叶目录的文件名、合并两个不同路径下图片文件名等目录/路径案例、正确加载图片路径)之详细攻略

    Python语言学习:利用python获取当前/上级/上上级目录路径(获取路径下的最后叶目录的文件名.合并两个不同路径下图片文件名等目录/路径案例.正确加载图片路径)之详细攻略 目录 利用python ...

  9. cv2.imread读取图像结果none_python cv2.imread 读取中文路径的图片返回为None的问题

    此篇文章首发于我的csdn博客,见原文链接. 使用cv2读取图片是常见的事情,但如果,输出图片形状大小时出现报错" 'NoneType' object has no attribute sh ...

最新文章

  1. autodesk许可证服务器,Autodesk软件工作流介绍(十)——配置网络许可服务器的步骤...
  2. ORM-Dapper:Dapper百科
  3. 详解C调用lua脚本效率测试
  4. Android httpUrlConnection的基本使用
  5. nullnulle-人事管理系统-人事档案-变更管理-人员合同变更
  6. 【CSS 】动画animation
  7. java w732_技术联盟W732系统下载
  8. 使用Executor管理Thread对象详解
  9. pads layout PCB整体旋转,不改变布局并保留连线
  10. python不调包实现sobel_python利用百度云接口实现车牌识别的示例
  11. 简单介绍几种Java后台开发常用框架组合
  12. 数据库的内连接和外连接的区别
  13. Android测试方法总结汇总
  14. 【常用模块】OLED显示模块(原理讲解、STM32实例操作)
  15. spring节假日定时发送阿里短信任务
  16. 编译相关(非原创 读书笔记)
  17. 台积电1nm,有新进展
  18. Scrum 5.0(继4.0)
  19. STM32+MAX6675 获取4路温度数据原理图及代码
  20. JAVA 18道基础循环练习题,带你了解循环是如何实现的(带答案)

热门文章

  1. mysql 浮点类型和定点_mysql 中的浮点和定点类型
  2. 计算尖峰电流的目的_183 新能源汽车电机控制器母线电容容值如何计算?
  3. Java基本数据类型及其包装类
  4. 关于 SpringCloud 配置,你了解多少?
  5. 计算机课作业在线管理,iwork学生作业在线系统
  6. java.io.file.sync_java.io.FileDescriptor#sync()是否特定于单个FileDescriptor
  7. freemarker 生成java_半自动化Java代码生成器[利用freemarker模板生成]
  8. SolrClient或SolrTemplate写入时连接solr服务器超时问题的一种解决方案
  9. Servlet学习笔记(四)之请求转发与重定向(RequestDispatcher与sendRedirect)
  10. Django 的系统时区设置 RPC