最短路径算法调研

关于最短路径算法的调研报告

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

摘要

最短路径算法的研究是计算机科学研究的热门话题,它不仅具有重要的理论意义,而且具有重要的实用价值。最短路径问题有广泛的应用,比如在交通运输系统,应急救助系统电子导航系统等研究领域。最短路径问题又可以引申为最快路径问题,最低费用问题等,但他们的核心算法都是最短路径算法。景点的最短路径算法——Dijkastra和Floyd算法是目前最短路径问题采用的理论基础。本文主要对Dijkstra和Floyd算法进行阐述和分析,然后运用这两个算法解决几个简单的实际问题。

关键词

离散数学   最短路径   Djkstra算法   Floyd算法   图论

 

 

 

 

 

 

 

 

 

 

 

最短路径

在一个无权的图中,若从一个定点到另一个定点存在着一条路径,则称该路径长度为该路径上所经过的边的数目,它等于该路径上的顶点数减1.由于从一个顶点到另一个顶点可能存在着多条路径,每条路径上经过的边数可能不同,即路径长度不同,把路径长度最短(即经过的边数最少)的那条路径叫做最短路径或者最短距离。

对于带权的图,考录路径上各边的权值,则通常吧一条路径上所经边的权值之和定义为该路径的路径长度或带权路径长度。从源点到终点可能不止一条路径,把带权路径长度最短的那条路径称为最短路径,其路径长度(权值之和)称为最短路径长度或最短距离。

实际上,只要把无权图上的每条边看成是权值为1的边,那么无权图和带权图的最短路径和最短距离的定义是一致的。

对于连接某对给定顶点的路径,可能有多条路径有相同的长度,因此最短路径问题的解不一定是唯一的,它可能有多个满足约束条件的解。

最短路径算法

求图中的最短路径有两方面的问题:求图中某一顶点到其余各顶点的最短路径与求图中每一对顶点之间的最短路径。他们有Dijkstra算法和Floyd算法,是目前两个比较著名的最短路径算法。

Dijkstra算法

Dijkstra算法一般的表述通常有两种方式,一种用永久和临时标号方式,一种是用OPEN, CLOSE表的方式,这里均采用永久和临时标号的方式。注意该算法要求图中不存在负权边。

1.首先,引入一个辅助向量D,它的每个分量 D表示当前所找到的从起始点(源点)到其它每个顶点的长度。

例如,D[3] = 2表示从起始点到顶点3的路径相对最小长度为2。这里强调相对就是说在算法执行过程中D的值是在不断逼近最终结果但在过程中不一定就等于长度。

2.D的初始状态为:若从有弧(即从存在连接边),则D为弧上的权(即为从的边的权值);否则置D。显然,长度为 D= Min{ D |V } 的路径就是从出发到顶点的长度最短的一条路径,此路径为()

3.那么,下一条长度次短的是哪一条呢?也就是找到从源点到下一个顶点的最短路径长度所对应的顶点,且这条最短路径长度仅次于从源点到顶点的最短路径长度。假设该次短路径的终点是,则可想而知,这条路径要么是(),或者是()。它的长度或者是从的弧上的权值,或者是D加上从的弧上的权值。

4.一般情况下,假设S为已求得的从源点出发的最短路径长度的顶点的集合,则可证明:下一条次最短路径(设其终点为)要么是弧(),或者是从源点出发的中间只经过S中的顶点而最后到达顶点的路径。因此,下一条长度次短的的最短路径长度必是D= Min{ D|V-S },其中D要么是弧()上的权值,或者是D(S)(,)上的权值之和。

算法描述如下:

1)令arcs表示弧上的权值。若弧不存在,则置arcs(在本程序中为MAXCOST)。S为已找到的从出发的的终点的集合,初始状态为空集。那么,从出发到图上其余各顶点可能达到的长度的初值为D=arcs[LocateVex(G,)]V

2)选择,使得D=Min{ D |V-S }

3)修改从出发的到集合V-S中任一顶点的最短路径长度。

基本思想

    设置顶点集合S并不断地作贪心选择来扩充这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。

初始时,S中仅含有源。设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度。Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组dist作必要的修改。一旦S包含了所有V中顶点,dist就记录了从源到所有其它顶点之间的最短路径长度。

例题实例

    对下图中的有向图,应用Dijkstra算法计算从源顶点1到其它顶点间最短路径

核心代码

#include <iostream>

usingnamespace std;

constint maxnum =100;

constint maxint =999999;

 

// 各数组都从下标1开始

int dist[maxnum];     // 表示当前点到源点的最短路径长度

int prev[maxnum];     // 记录当前点的前一个结点

int c[maxnum][maxnum];   // 记录图的两点间路径长度

int n, line;             // 图的结点数和路径数

void Dijkstra(int n, int v, int*dist, int*prev, int c[maxnum][maxnum])

{

      bool s[maxnum];    // 判断是否已存入该点到S集合中

      for(int i=1; i<=n;++i)

      {

            dist[i]= c[v][i];

            s[i]=0;    // 初始都未用过该点

            if(

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值