zoukankan      html  css  js  c++  java
  • 最短路径问题

    ---------------------siwuxie095

       

       

       

       

       

       

       

    最短路径问题

       

       

    这里介绍最短路径(Shortest Path)问题

       

       

       

       

       

    实现最短路径的算法,通常是针对连通带权有向图的,但由于

    无向图本身也是一种特殊的有向图,所以对于无向图有向图

    均成立

       

       

    所谓最短路径问题,顾名思义,就是求出从一个顶点到另一个

    顶点,耗费最小(即 权值之和最小)的那条路径

       

       

       

       

       

    最短路径问题在实际生活中有很多应用,如下:

       

    1)路径规划

       

    假如每个顶点表示一个城市,每条边表示城市之间道路的路程,

    那么从一个城市到另一个城市,自然愿意选择一个路程最短的

    道路

       

       

    2)路由通信

       

    假如在网络中,每个顶点表示一个路由器,每条边表示路由之

    间通信的耗费,那么将一个网络包从一点发送到另一点,路由

    器之间如何寻址,从而找到一个更优的路线,就是一个最短路

    径问题

       

       

    3)工作任务规划

       

    假如在工作中,每个顶点表示一个工作任务,每条边表示工作

    任务之间的时间,那么从一个工作任务到另一个工作任务,中

    间选择完成哪些子任务耗费时间更少,也是一个最短路径问题

       

       

       

       

       

    其实在无权图中,也有最短路径问题。对于无权图,从某顶点

    开始进行广度优先遍历,结果其实就是求出了一个最短路径

       

    更具体的,求出的是从一个顶点到其它所有顶点的最短路径

       

    这样一来,就形成了一棵从起始顶点到其它所有顶点的树,通

    常称这棵树为 最短路径树(Shortest Path Tree)

       

    不难看出,这棵树其实也是该无权图的生成树,它满足的性质

    是:所有顶点到起始顶点的距离最小

       

       

       

    求得最短路径树的过程,解决了一个通常称为单源最短路径

    (Single Source Shortest Path)的问题

       

    「单源,即 只有一个起始点」

       

    换句话说,广度优先遍历就是解决了在无权图中的单源最短路

    径问题

       

       

       

       

       

    那么在有权图中,又如何来解决单源最短路径问题呢?首先来

    看无权图和有权图的区别,如下:

       

    1)无权图的最短路径,将 0 作为起始顶点

       

       

       

    0 开始,可以通过一条边到 1,即 0 -> 1,可以通过一条边

    2,即 0 -> 2

       

       

       

    0 开始进行广度优先遍历,就遍历到了 1 2,它们的路径

    长度都是 1,如下:

       

       

       

    此时在无权图中,显然已经是最短路径了,虽然 0 -> 2 -> 1

    也是一条到达 1 的路径,但它不可能是比 0 ->1 更短的路径

       

       

       

       

       

    2)有权图的最短路径,将 0 作为起始顶点

       

       

    三条边都有权,权值如上图所示

       

       

       

    0 开始,可以通过一条边到 1,即 0 ->1,可以通过一条边

    2,即 0 -> 2,如下:

       

       

       

    但此时,并不能确定只通过这一条路径(一条边)所得的权值

    一定是最小的

       

       

       

    由于从 2 也可以通过一条边到 1,就要考察一下 0 -> 2 -> 1

    是否比 0 -> 1 的路径还要短,如下:

       

       

       

    显然,0 -> 2 -> 1 的路径是短于 0 -> 1 的路径的。因此,

    就找到了一条更短的路径

       

    「注意:路径更短 即 权值更小,路径 权值」

       

       

       

       

       

    求有权图的最短路径的过程:

       

    前提条件:

       

    1)起始顶点 当前顶点 相邻顶点

       

    2)相邻顶点 当前顶点的相邻顶点

       

       

    操作如下:

       

    从起始顶点开始

       

    当到达当前顶点时,就尝试一下经过当前顶点到相邻顶点所得

    到的路径,是否比不经过当前顶点到相邻顶点所得到的路径更

    短。如果更短,就更新一下从起始顶点到相邻顶点的当前最短

    路径

       

       

    称这个操作为 松弛操作(Relaxation)

       

       

    松弛操作的核心当前顶点,看它的相邻顶点是否需要松弛,

    每次松弛操作,实际上是对相邻顶点的访问

       

       

    所谓松弛,其实是找到了一条更短的路径,但该路径的边数其

    实更多,单从图上也能看出来,其实就是找到了一条直观上

    了的路径,是一条更松的路径

       

       

    「松弛操作,是最短路径问题求解的核心」

       

       

    对于松弛操作,不管有多少个顶点,其实都可以看做是一个

    角形操作,如下:

       

    1)一条线:两个顶点:0 -> 1

       

    0 既是起始顶点,又是当前顶点,1 是相邻顶点

       

       

    2)四边形:四个顶点:0 -> 1 -> 2 -> 3 0 -> 3,

    0 -> 1 -> 2 加上 2 -> 3 的权值小于 0 -> 3 的权值

       

    0 是起始顶点,2 是当前顶点,3 是相邻顶点

       

       

       

    其它所有情况都是以上两种情况的变形,只要确认好起始顶点

    当前顶点相邻顶点即可

       

       

       

       

       

       

       

       

       

    【made by siwuxie095】

  • 相关阅读:
    C语言II—作业03
    C语言II博客作业01
    学期总结
    第一次作业!
    C语言I博客作业08
    C语言I博客作业07
    C语言I博客作业06
    C语言I博客作业05
    C语言I博客作业04
    第三次作业!
  • 原文地址:https://www.cnblogs.com/siwuxie095/p/7135483.html
Copyright © 2011-2022 走看看