转载自:http://blog.csdn.net/fengchaokobe/article/details/7478774
  
第一节 问题的提出及解决方法
       所谓最短路径问题,可以说有两种情况来描述。
       描述一:在图论中,指的是寻找图中两个节点之间的最短距离。如下图

       描述二:在现实生活中,指的是找到从一个地方到另一个地方的最近距离。如下图

       上述两种情况的本质是一样的,即求一个点到另一个点的最短路径。好了,问题已经提出来了,那怎么解决呢?解决该问题的方法还是比较多的,不过由于各个路径算法所对应的问题条件不同,我们可根据不同的情况,选择不同的路径算法。
       本文将介绍三种最短路径算法,分别是:戴克斯特拉算法(Dijkstra algorithm),弗洛伊德算法(Floyd algorithm)以及A*搜索算法。

第二节 戴克斯特拉算法(Dijkstra algorithm)
       该算法解决的是有向图中单个源点到其他顶点的最短路径问题。

戴克斯特拉算法的实现过程如下:
       第一步:用带权的矩阵WeiArcs来表示带权有向图,如果图中的两个顶点vi和vj是连通的,则用WeiArcs[i][j]表示这两个顶点所形成边的权值;如果vi和vj不连通,即<vi,vj>这条边不存在,那么将WeiArcs[i][j]置为∞。
       第二步:设S为已求得的从某一顶点v始发的最短路径的终点的集合,且S的初始状态为空,初始化时,将始发顶点置于S集合中。那么从v出发到图中其余各个顶点vi可能达到的最短路径长度的初值为D[i]。
       第三步:选择一顶点vj,使得vj就是当前求得的一条从顶点v出发的最短路径的终点。此时令S = S ∪ {vj}。
       第四步:修改从v出发到集合V-S(V为图顶点的集合)中任一顶点vk可达的最短路径长度。如果D[j]+WeiArcs[j][k] < D[K],则D[k] = D[j] + WeiArcs[j][k]。
       第五步:重复操作第三步、第四步共N-1次,由此就能求得从v出发到图中其余各个顶点的最短路径。

好了,实现过程就是这样。不过光有文字描述不行,要更直白的表达这个过程,我认为用图像表述是一个很好的选择。如下图所示

从运算过程表中,我们可知v0到其余个点的最短路径,如下图

上述过程描述的戴克斯特拉算法的代码如下:
int ShortPath(MGraph G,int v0,PathMatrix &P,ShortPathTable &D)
{  //用戴克斯特拉算法求有向图G中v0顶点到其余顶点v的最短路径P[v]及带权长度D[v]。  //若P[v][w]为TRUE,则w是从v0到v当前求得最短路径上的顶点。  //final[v]为TRUE当且仅当v∈S,即已经求得从v0到v的最短路径。  for(v = 0;v < G.vexmun;v++)  {  final[v] = FALSE;  D[v] = G.WeiArcs[v0][v];  for(w = 0;w < G.vexnum;w++)  P[v][w] = FALSE;    //设空路径  if(D[v] < INFINITY)  {  p[v][v0] = TRUE;  p[v][v] = TRUE;  }  }  D[v0] = 0;final[v0] = TRUE; //初始化,v0顶点属于S集合  //开始主循环,每次求得v0到某个顶点v的最短路径,并将v加到S集合中  for(i = 1; i < G.vexnum; i++)    //其余G.vexnum - 1个顶点  {  min = INFINITY; //当前所知离v0点的最近距离  for(w = 0;w < G.vexnum; i++)  {  if(!final[w])   //w顶点在V - S中  {  if(D[w] < min)   //w顶点离v0更近  {  v = w;  min = D[w];  }  }  }  final[v] = TRUE;    //离v0顶点最近的v加入到S中  for(w = 0;w < G.vexnum;w++)  //更新当前最算路径及距离  {  if(!final[w] && (min + G.WeiArcs < D[w]))  {  D[w] = min + G.WeiArcs[v][w];  //p[w] = P[v] + P[w];  P[w] = P[v];  P[w][w] = TRUE;  }  }  }  return 0;
}  

ok,Dijkstra algorithm介绍完了。

第三节 弗洛伊德算法(Floyd algorithm)
       该算法解决的是有向带权图中两顶点之间最短路径的问题。

弗洛伊德算法的设计过程如下:
       用带权的矩阵WeiArcs来表示带权有向图,如果图中的两个顶点vi和vj是连通的,则用WeiArcs[i][j]表示这两个顶点所形成边的权值;如果vi和vj不连通,即<vi,vj>这条边不存在,那么将WeiArcs[i][j]置为∞。
       要求:求节点vi到节点vj的最短路径。
       设D(i,j,k)为从节点vi到节点vj的以vk(vk∈(0,1,...k))节点为中间节点的最短路径的长度。例如:从vi到vj这条路径上经过节点vm和节点vk,那么可表示为:vi-->vm-->vk-->vj。

那么,就有:1.若最短路径经过节点vk,则D(i,j,k) = D(i,k,k-1) + D(k,j,k-1);
                      2.若最短路径不经过节点vk,则D(i,j,k) = D(i,j,k-1)。
所以,求的vi到vj的最短路径可表示为:

D(i,j,k) = min(D(i,k,k-1) + D(k,j,k-1), D(i,j,k-1))。

老办法,图示的过程如下:

求解的过程见下图:


上述过程描述的弗洛伊德算法的代码如下:
int ShortPath(MGraph G,int v0,PathMatrix &P,ShortPathTable &D)
{  //用Floyd算法求有向图中各对顶点v和w之间的最短路径P[v][w]及其带权长度D[v][w]。  //若p[v][w][u]为TRUE,则u是从v到w当前求得的最短路径上的顶点  for(v = 0;v < G.vexnum;v++)  for(w = 0;w < G.vexnum;w++)  {  D[v][w] = G.arcs[v][w];  if(D[v][w] < INFINITY)   //从v到w有直接路径  {  P[v][w][u] = TRUE;  P[v][w][w] = TRUE;  }  }  for(u = 0;u < G.vexnum;u++)  for(v = 0;v < G.vexnum;v++)  for(w = 0;w < G.vexnum;w++)  {  if(D[v][u] + D[u][w] < D[v][w])  //从v经u到w的一条更短路径  D[v][w] = D[v][u] < D[u][w];  for(i = 0;i < G.vexnum;i++)  P[v][w][i] = P[v][u][i] || P[u][w][i];  }  return 0;
}

第四节 A*搜索算法
       A*搜索算法,俗称A星算法。这是一种在图平面上,有多个节点的路径,求出最低通过成本的算法。常用于游戏中的NPC的移动计算,或线上游戏的BOT的移动计算上。该算法像Dijkstra算法一样,可以找到一条最短路径;也像BFS一样,进行启发式的搜索。

A*算法最核心的部分,就在于它的一个估值函数的设计上:f(n)=g(n)+h(n)。其中,g(n)表示从起始点到任一点n的实际距离,h(n)表示任意顶点n到目标顶点的估算距离,f(n)是每个可能试探点的估值。这个估值函数遵循以下特性:
       •如果h(n)为0,只需求出g(n),即求出起点到任意顶点n的最短路径,则转化为单源最短路径问题,即Dijkstra算法;
       •如果h(n)<=“n到目标的实际距离”,则一定可以求出最优解。而且h(n)越小,需要计算的节点越多,算法效率越低。

我们可以这样来描述:从出发点(StartPoint,缩写成sp)到终点(EndPoint,缩写成ep)的最短距离是一定的,于是我们可以写一个估值函数来估计出发点到终点的最短距离。如果程序尝试着从出发点沿着某条线路移动到了路径上的另一个点(Otherpoint,缩写成op),那么我们认为这个方案所得到的从sp到ep间的估计距离为:从sp到op实际已走的距离加上估计函数估出的从op到ep的距离。如此,无论我们的程序搜索展开到哪一步,都会得到一个估计值,每一次决策后,将评估值和等待处理的方案一起排序,然后挑出待处理的各个方案中最有可能是最短路线的一部分的方案展开到下一步, 一直循环直到对象移动到目的地,或所有方案都尝试过,却没有找到一条通向目的地的路径则结束。

A*搜索算法的图解过程请看:http://blog.vckbase.com/panic/archive/2005/03/20/3778.html

第五节 相关说明
参考资料:数据结构(严蔚敏)、维基百科之A*搜索算法

第六节 结束语
      想想,写写,画画......

深入解析最短路径算法相关推荐

  1. 我是怎么使用最短路径算法解决动态联动问题的

    省市县三级联动问题相信大家都耳熟能详了,选择市下拉选项依赖于省,同样的选择县下拉选项依赖于市.把省市县抽象成三个节点A(省),B(市),C(县),它们的关系如下图(1).假如把这个联动问题复杂化一点如 ...

  2. 沃舍尔算法_[数据结构拾遗]图的最短路径算法

    前言 本专题旨在快速了解常见的数据结构和算法. 在需要使用到相应算法时,能够帮助你回忆出常用的实现方案并且知晓其优缺点和适用环境.并不涉及十分具体的实现细节描述. 图的最短路径算法 最短路径问题是图论 ...

  3. 带权图的最短路径算法(Dijkstra)实现

    一,介绍 本文实现带权图的最短路径算法.给定图中一个顶点,求解该顶点到图中所有其他顶点的最短路径 以及 最短路径的长度.在决定写这篇文章之前,在网上找了很多关于Dijkstra算法实现,但大部分是不带 ...

  4. 图论:图的四种最短路径算法

    目录: 1.DFS(单源最短路径算法) 例题1: DFS题目分析: 代码DFS: 2.Floyed(时间复杂度On^3) 1.应用场景: 2.解析算法: 核心代码1: 我的笔记 核心代码2: Floy ...

  5. 最短路径算法---有向图

    最短路径算法---有向图. 最短路算法 最常用的最短路算法是Dijkstra算法.A*算法.SPFA算法.Bellman-Ford算法和Floyd-Warshall算法,我们这里重点介绍并实现Dijk ...

  6. 【从蛋壳到满天飞】JS 数据结构解析和算法实现-AVL树(一)

    前言 [从蛋壳到满天飞]JS 数据结构解析和算法实现,全部文章大概的内容如下: Arrays(数组).Stacks(栈).Queues(队列).LinkedList(链表).Recursion(递归思 ...

  7. (最短路径算法整理)dijkstra、floyd、bellman-ford、spfa算法

    一.floyd 1.介绍 floyd算法只有五行代码,代码简单,三个for循环就可以解决问题,所以它的时间复杂度为O(n^3),可以求多源最短路问题. 2.思想: Floyd算法的基本思想如下:从任意 ...

  8. Bellman-Ford 单源最短路径算法

    Bellman-Ford 单源最短路径算法 Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法.该算法由 R ...

  9. 最短路径算法——Dijkstra and Floyd算法

    一.     前言:     这个古老的算法应该耳熟能详了吧,但是我自从从学校出来到现在,最短路径算法都没有实际运用过,最近在一个GIS项目中总算用到了,于是乎把教材重温了下,同时查阅了网上很多的资料 ...

最新文章

  1. KVM中vhost-user简介(十三)
  2. substr判断最后一个是不是逗号_用java帮助你判断一个数是不是回文数
  3. 外媒:下代iPad Pro将同时具备无线充电和反向无线充电功能
  4. WIN10和XP共享及XP添加WIN10共享打印机方法
  5. oracle 11g压缩分区表,ORACLE 10g和11g压缩分区表操作脚本
  6. 欧洲最大笔融资,骗过软银!印度AI公司被曝造假,自动开发背后是真人码农
  7. Pseudo-terminal will not be allocated because stdin is not a terminal. Warning: Permanently added ‘[
  8. 2015iMAC安装macOS/Win11双系统 外置硬盘安装macOS/Win11双系统(非PE非DP虚拟机非WTG)
  9. python之shapely库的使用
  10. 一文讲清:对象存储、文件存储、块存储。绝对好文
  11. 搜狗拼音Lunix系統-乱码及繁体解决
  12. 编辑/调试汇编语言所需要工具
  13. JDK环境变量配置环境变量版本查询
  14. 跨平台的UML工具——Jude(astah)
  15. 获取微信昵称、头像等信息方法
  16. 连接服务器失败可能是oracle net,ora-28547:连接服务器失败,可能是 Oracle Net 管理失败...
  17. 2023最新版Java面试八股文PDF版限时分享,含800道高频面试题
  18. ALSA-hda开发笔记
  19. 042计算学生的平均身高
  20. 【已解决】UnknownError: Failed to get convolution algorithm. This is probably because cuDNN failed to ini

热门文章

  1. 小米12和iQOOneo5s参数对比
  2. 基于SpringBoot的图书管理系统(JavaWeb)
  3. 计算机二级c相关书籍,二级C
  4. 民间借贷合同的违约金应约定多少
  5. 应用密码学与网络安全上机题通关秘籍
  6. socket编程二十二:socket编程实现文件传输功能
  7. 桥梁结构健康监测系统-桥梁健康监测方案介绍
  8. 关于印象笔记的扫描宝——简单的图像背景去除(去底色)算法小结
  9. 微信H5页面隐藏点击右上角的分享功能
  10. 【面经】2022年软件测试面试题总结(附答案)