Dijkstra算法

一.最短路径的最优子结构性质

该性质描述为:如果P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径,k和s是这条路径上的一个中间顶点,那么P(k,s)必定是从k到s的最短路径。下面证明该性质的正确性。

假设P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径,则有P(i,j)=P(i,k)+P(k,s)+P(s,j)。而 P(k,s)不是从k到s的最短距离,那么必定存在另一条从k到s的最短路径P'(k,s),那么 P'(i,j)=P(i,k)+P'(k,s)+P(s,j)<P(i,j)。则与P(i,j)是从i到j的最短路径相矛盾。因此该性质得证。

二.Dijkstra算法

由上述性质可知,如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点。那么(Vi...Vk)也必定是从i到k的最短 路径。为了求出最短路径,Dijkstra就提出了以最短路径长度递增,逐次生成最短路径的算法。譬如对于源顶点V0,首先选择其直接相邻的顶点中长度最 短的顶点Vi,那么当前已知可得从V0到达Vj顶点的最短距离dist[j]=min{dist[j],dist[i]+matrix[i][j]}。根 据这种思路,

假设存在G=<V,E>,源顶点为V0,U={V0},dist[i]记录V0到i的最短距离,path[i]记录从V0到i路径上的i前面的一个顶点。

1.从V-U中选择使dist[i]值最小的顶点i,将i加入到U中;

2.更新与i直接相邻顶点的dist值。(dist[j]=min{dist[j],dist[i]+matrix[i][j]})

3.知道U=V,停止。

三.算法实例

先给出一个无向图

用Dijkstra算法找出以A为起点的单源最短路径步骤如下

代码:

#include <iostream>
#include <cstring>
using namespace std; #define DEBUG 0
#define INF 0x7fffffff
#define MAX 20 int N, V;
int graph[MAX][MAX];
int dist[MAX];
int prev[MAX];
bool visited[MAX]; void PrintPath()
{
for( int i = ; i <= V; i++ )
{
cout << "1 --> " << i << " : " << dist[i] << endl;
} for( int i = ; i <= V; i++ ) //计算从1到每个顶点的距离
{
int path[MAX] = {};
int step = ;
int cur = i;
do
{
path[step++] = cur;
cur = prev[cur];
}
while( cur != - ); //前一个点为-1,则结束 for( int j = step - ; j >= ; j-- )
{
cout << path[j] << " ";
}
cout << endl;
}
} int GetMinDist()
{
int index, min = INF;
for( int i = ; i <= V; i++ )
{
if( !visited[i] && min > dist[i] )
{
min = dist[i];
index = i;
}
}
return index;
} void Dijkstra( int v )
{
for( int i = ; i <= V; i++ )
{
if( graph[v][i] == INF )
{
dist[i] = INF;
prev[i] = -;
}
else
{
dist[i] = graph[v][i];
prev[i] = v;
}
visited[i] = false;
} dist[v] = ;
visited[v] = true; for( int i = ; i < V; i++ ) //迭代V-1次,不用计算源点了,还剩下V-1个需要计算的顶点
{
int u = GetMinDist(); visited[u] = true; for( int j = ; j <= V; j++ ) //更新dist数组
{
if( visited[j] == false && graph[u][j] != INF && dist[u] != INF && dist[j] > dist[u] + graph[u][j] )
{
dist[j] = dist[u] + graph[u][j];
prev[j] = u;
}
}
}
} void InitData()
{
memset( visited, false, sizeof( visited ) ); //初始化visited for( int i = ; i <= V; i++ )
{
for( int j = ; j <= V; j++ )
{
graph[i][j] = INF;
}
dist[i] = INF;
}
} int main()
{
int a, b, value;
while( cin >> V, V ) // 输入顶点数
{
cin >> N; //输入边数
InitData();
for( int i = ; i <= N; i++ )
{
cin >> a >> b >> value;
graph[a][b] = graph[b][a] = value;
} Dijkstra( );
PrintPath();
}
}

输入文件:

/*

6 10
1 2 4
1 3 8
2 3 3
2 4 4
2 5 6
3 4 2
3 5 2
4 5 4
4 6 9
5 6 4 result :
1 --> 1 : 0
1 --> 2 : 4
1 --> 3 : 7
1 --> 4 : 8
1 --> 5 : 9
1 --> 6 : 13
1
1 2
1 2 3
1 2 4
1 2 3 5
1 2 3 5 6 */

Floyd算法

1.算法思想原理:

Floyd算法是一个经典的动态规划算法。从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从i到j,2是从i经过若干个节点k到j。所以,假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,则设置Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。

2.算法描述:

a.从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。   

b.对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比己知的路径更短。如果是更新它。

3.Floyd算法过程矩阵的计算----十字交叉法

方法:两条线,从左上角开始计算一直到右下角 如下所示

给出矩阵,其中矩阵A是邻接矩阵,而矩阵Path记录u,v两点之间最短路径所必须经过的点

相应计算方法如下:

最后A3即为所求结果.

算法实现:

#include <iostream>

using namespace std;

#define INF 65536
#define MAX 20 int graph[MAX][MAX];
int KeyPoint[MAX][MAX];
int V, E; void PrintPath()
{
cout << graph[][V] << endl; int path[MAX];
int step = ;
int cur = V; while(cur != ) {
path[step++] = cur;
cur = KeyPoint[][cur];
} path[step++] = ; //保存起点 for (int j = step - ; j >= ; j--)
{
cout << path[j] << " ";
}
cout << endl;
} void Floyd()
{
graph[][] = ; for(int k = ; k <= V; k++) //对于每一个节点k,检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立
for(int i = ; i <= V; i++)
for(int j = ; j <= V; j++)
if(graph[i][j] > graph[i][k] + graph[k][j])
{
graph[i][j] = graph[i][k] + graph[k][j];
KeyPoint[i][j] = k;
}
PrintPath();
} void InitData()
{
for(int i = ; i <= V; i++)
{
for(int j = ; j <= V; j++)
{
graph[i][j] = INF;
KeyPoint[i][j] = ;
}
}
} int main()
{
int a, b, length;
while(cin >> V, V) //输入顶点数
{
InitData(); cin >> E; //输入边数
for(int i = ; i <= E; i++)
{
cin >> a >> b >> length;
graph[a][b] = graph[b][a] = length;
} Floyd();
}
}

测试用例

/*

6 10
1 2 4
1 3 8
2 3 3
2 4 4
2 5 6
3 4 2
3 5 2
4 5 4
4 6 9
5 6 4 result:
13
1 2 3 5 6 */

Algorithm --> Dijkstra和Floyd最短路径算法的更多相关文章

  1. Dijkstra 单源最短路径算法

    Dijkstra 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法,由计算机科学家 Edsger Dijkstra 于 1956 年 ...

  2. Floyd最短路径算法

    看完这篇文章写的小程序,Floyd最短路径算法,求从一个点到另一个点的最短距离,中间可以经过其他任意个点.三个for循环,从i到j依次经过k的最短距离,最外层for循环是经过点K,内部两个循环是从i( ...

  3. Dijkstra单源点最短路径算法

    学习参考: Dijkstra算法(单源最短路径) 最短路径—Dijkstra算法和Floyd算法 使用的图结构: 邻接矩阵: -1 20 -1 25 80-1 -1 40 -1 -1-1 -1 -1 ...

  4. Floyd最短路径算法(来自微信公众号“算法爱好者”改编)

    暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程. 上图中有4个城市8条公路,公路上的数字表 ...

  5. 【模板 && 拓扑】 Dijkstra 单源最短路径算法

    话不多说上代码 链式前向星233 #include<bits/stdc++.h> using namespace std; ,_max=0x3fffffff; //链式前向星 struct ...

  6. 图之单源Dijkstra算法、带负权值最短路径算法

    1.图类基本组成 存储在邻接表中的基本项 /** * Represents an edge in the graph * */ class Edge implements Comparable< ...

  7. 一篇文章讲透Dijkstra最短路径算法

    Dijkstra是典型最短路径算法,计算一个起始节点到路径中其他所有节点的最短路径的算法和思想.在一些专业课程中如数据结构,图论,运筹学等都有介绍.其思想是一种基础的求最短路径的算法,通过基础思想的变 ...

  8. Johnson 全源最短路径算法

    解决单源最短路径问题(Single Source Shortest Paths Problem)的算法包括: Dijkstra 单源最短路径算法:时间复杂度为 O(E + VlogV),要求权值非负: ...

  9. Floyd-Warshall 全源最短路径算法

    Floyd-Warshall 算法采用动态规划方案来解决在一个有向图 G = (V, E) 上每对顶点间的最短路径问题,即全源最短路径问题(All-Pairs Shortest Paths Probl ...

随机推荐

  1. 集成电路883和883b有什么区别

    根据用途,元器件的质量等级可分为:用于元器件生产控制.选择和采购的质量等级和用于电子设备可靠性预计的质量等级两类,两者有所区别,又相互联系. 用于元器件生产控制.选择和采购的质量等级 元器件的质量等级 ...

  2. Hidden Markov Models(HMM) 初理解

    1. 一个简单例子

  3. MyEclipse提示

    MyEclipse提示 1.具体如下图 2.提示原因 3.解决办法

  4. 一款PHP环境整合工具—VertrigoServ介绍

    Vertrigo简介 VertrigoServ 是一个Windows平台下的非常专业的.易于安装的免费网络开发环境,它集成了Apache, PHP, MySQL, SQLite, SQLiteMana ...

  5. Web站点错误提示页面和默认访问页面设置

    1.asp.net 定制简单的错误处理页面 通常web应用程序在发布后,为了给用户一个友好界面和使用体验,都会在错误发生时跳转至一个自定义的错误页面,而不是asp.net向用户暴露出来的详细的异常列表 ...

  6. 如何开发jQuery插件

    一:普及JQuery知识 知识1:用JQuery写插件时,最核心的方法有如下两个: $.extend(object) 可以理解为,为JQuery 类添加一个静态方法. $.fn.extend(obje ...

  7. img 标签 访问图片 返回403 forbidden问题

    之前在项目里,本地调试的时候,图片src引用了第三方网站的图片资源,导致控制台出现了如下的报错: 403 forbidden,说明了这个网络资源这样获取是被拒绝的,那么通过简单的百度,找到了相关的解决 ...

  8. mfc100u.dll下载和使用方法

      当运行软件或游戏时,系统提示"丢失mfc100u.dll"."没有找到mfc100u.dll"等类似错误信息. 请下载本站提供的dll文件,使用它可以帮助用 ...

  9. Keras官方中文文档:关于Keras模型

    关于Keras模型 Keras有两种类型的模型,序贯模型(Sequential)和函数式模型(Model),函数式模型应用更为广泛,序贯模型是函数式模型的一种特殊情况. 两类模型有一些方法是相同的: ...

  10. [BZOJ3460] Jc的宿舍

    bzoj 题面放一下 Description WC2014后无数人来膜拜jc,但是来膜拜的人实在太多了, 而且很多人是一连膜拜好几天.所以jc给这些人建了一座树 形的宿舍,而根节点(1号节点)住着jc ...