1.单源点的最短路径问题:给定带权有向图G和源点v,求从v到G中其余各顶点的最短路径。

我们用一个例子来具体说明迪杰斯特拉算法的流程。

定义源点为 0,dist[i]为源点 0 到顶点 i 的最短路径。其过程描述如下:

步骤 dist[1] dist[2] dist[3] dist[4] 已找到的集合
第 1 步 8 1 2 +∞ {2}
第 2 步 8 × 2 4 {2, 3}
第 3 步 5 × × 4 {2, 3, 4}
第 4 步 5 × × × {2, 3, 4, 1}
第 5 步 × × × × {2, 3, 4, 1}

第 1 步:从源点 0 开始,找到与其邻接的点:1,2,3,更新dist[]数组,因 0 不与 4 邻接,故dist[4]为正无穷。在dist[]中找到最小值,其顶点为 2,即此时已找到 0 到 2 的最短路。

第 2 步:从 2 开始,继续更新dist[]数组:2 与 1 不邻接,不更新;2 与 3 邻接,因0→2→3dist[3]大,故不更新dist[3] ;2 与 4 邻接,因0→2→4dist[4]小,故更新dist[4]为 4。在dist[]中找到最小值,其顶点为 3,即此时又找到 0 到 3 的最短路。

第 3 步:从 3 开始,继续更新dist[]数组:3 与 1 邻接,因0→3→1dist[1]小,更新dist[1]为 5;3 与 4 邻接,因0→3→4dist[4]大,故不更新。在dist[]中找到最小值,其顶点为 4,即此时又找到 0 到 4 的最短路。

第 4 步:从 4 开始,继续更新dist[]数组:4 与 1 不邻接,不更新。在dist[]中找到最小值,其顶点为 1,即此时又找到 0 到 1 的最短路。

第 5 步:所有点都已找到,停止。

对于上述步骤,你可能存在以下的疑问:

若 A 作为源点,与其邻接的只有 B,C,D 三点,其dist[]最小时顶点为 C,即就可以确定A→C为 A 到 C 的最短路。但是我们存在疑问的是:是否还存在另一条路径使 A 到 C 的距离更小? 用反证法证明。

假设存在如上图的红色虚线路径,使A→D→C的距离更小,那么A→D作为A→D→C的子路径,其距离也比A→C小,这与前面所述 “dist[]最小时顶点为 C” 矛盾,故假设不成立。因此这个疑问不存在。

根据上面的证明,我们可以推断出,Dijkstra 每次循环都可以确定一个顶点的最短路径,故程序需要循环 n-1 次。

/*
迪杰斯特拉求单节点到其余各节点的最短路径。
visited数组用于保存顶点是否已经求过最短路径,pre数组用于保存最短路径的下标
dist数组用于保存初始节点到其余节点的最短路径长度。
该算法求有向图G的某顶点到其余节点的最短路径pre以及长度dist
pre[v]的值是v0-->...->v的路径中的前驱节点。D[v]表示v0-->...-->v的最短路径长度和。 可以证明迪杰斯特拉算法每次循环可以确定一个顶点的最短路径,所以主程序循环n-1次。
主程序循环主要做两件事:首先找出dist数组中的最小值,并记录下标,说明找到初始点到该下标的最短路径。
然后要比价初始点到该点的最短路径加上这点到其他初始点需要到的点的距离是否比初始点直接到这些点的距离短
如果要短,那么就更新dist数组,并且这些点的前驱节点就会变为v而不是开始的v0点。下一次主循环再去从dist中找
最小的值并且未求过的点,就是该点的最短路径。
*/
#include<iostream>
using namespace std;
int matrix[][];//邻接矩阵
bool visited[];//标记数组
int dist[];//原点到i顶点的最短距离
int pre[];//记录最短路径。pre[i]放的是i的前驱节点
int source;//源节点
int vertex_num;//顶点数
int edge_num;//边数 void Dijkstra(int source)
{
//首先初始化
memset(visited,,sizeof(visited));
visited[source] = true;
for (int i = ; i < vertex_num; i++)
{
dist[i] = matrix[source][i];
pre[i] = source;
} int min_cost;//最短距离
int min_cost_index;//权值最小的那个顶点的下标。(求好了)
//主循环
for (int i = ; i < vertex_num; i++)
{
min_cost = INT_MAX;
for (int j = ; j < vertex_num; j++)
{
//注意要确保这个点没有找过。
if (visited[j]==false&&dist[j] < min_cost)
{
min_cost_index = j;
min_cost = dist[j];
}
} visited[min_cost_index] = true;//找到某一个点的最短距离
//利用该点进行dist的更新,并且调整前驱。
for (int j = ; j < vertex_num; j++)
{
//确保有连接
if (visited[j] == false && matrix[min_cost_index][j] != INT_MAX&&min_cost+ matrix[min_cost_index][j] < dist[j])
{
dist[j] = min_cost + matrix[min_cost_index][j];
pre[j] = min_cost_index;
}
}
}
} int main()
{
cout << "请输入图的顶点数(<100):";
cin >> vertex_num;
cout << "请输出图的边数: ";
cin >> edge_num;
for (int i = ; i < vertex_num; i++)
{
for (int j = ; j < vertex_num; j++)
{
matrix[i][j] = (i != j) ? INT_MAX : ;
}
}
cout << "请输入边的信息:\n";
int u, v, w;
for (int i = ; i < edge_num; i++)
{
cin >> u >> v >> w;
matrix[u][v] = matrix[v][u] = w;
} cout << "请输入源点(<" << vertex_num << "): ";
cin >> source;
Dijkstra(source);
for (int i = ; i < vertex_num; i++)
{
if (i != source)
{
//路径是反的,从目标点向前不断找前驱的过程。
cout << source << "到" << i << "最短距离: " << dist[i] << ",路径是:" << i;
int t = pre[i];
while (t != source)
{
cout << "--" << t;
t = pre[t];
}
cout << "--" << source << endl;
}
}
return ;
}

2、弗洛伊德算法:

1)算法思想原理:

Floyd算法是一个经典的动态规划算法。用通俗的语言来描述的话,首先我们的目标是寻找从点i到点j的最短路径。从动态规划的角度看问题,我们需要为这个目标重新做一个诠释(这个诠释正是动态规划最富创造力的精华所在)

从任意节点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即为所求结果

typedef struct
{
char vertex[VertexNum]; //顶点表
int edges[VertexNum][VertexNum]; //邻接矩阵,可看做边表
int n,e; //图中当前的顶点数和边数
}MGraph; void Floyd(MGraph g)
{
  int A[MAXV][MAXV];
  int path[MAXV][MAXV];
  int i,j,k,n=g.n;
  for(i=;i<n;i++)
  for(j=;j<n;j++)
  {   
A[i][j]=g.edges[i][j];
   path[i][j]=-;
  }
  for(k=;k<n;k++)
  {
  for(i=;i<n;i++)
  for(j=;j<n;j++)
  if(A[i][j]>(A[i][k]+A[k][j]))
  {
  A[i][j]=A[i][k]+A[k][j];
  path[i][j]=k;
  }
 }
}

//代码来自于wsw_seu大佬

//仅仅是作为笔记,谢谢

最小路径算法(Dijkstra算法和Floyd算法)的更多相关文章

  1. 最短路径——Dijkstra算法和Floyd算法

    Dijkstra算法概述 Dijkstra算法是由荷兰计算机科学家狄克斯特拉(Dijkstra)于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图(无 ...

  2. 【转载】Dijkstra算法和Floyd算法的正确性证明

      说明: 本文仅提供关于两个算法的正确性的证明,不涉及对算法的过程描述和实现细节 本人算法菜鸟一枚,提供的证明仅是自己的思路,不保证正确,仅供参考,若有错误,欢迎拍砖指正   ----------- ...

  3. Dijkstra算法和Floyd算法的正确性证明

    说明: 本文仅提供关于两个算法的正确性的证明,不涉及对算法的过程描述和实现细节 本人算法菜鸟一枚,提供的证明仅是自己的思路,不保证正确,仅供参考,若有错误,欢迎拍砖指正   ------------- ...

  4. 最短路径Dijkstra算法和Floyd算法整理、

    转载自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最短路径—Dijkstra算法和Floyd算法 Dijks ...

  5. 【转】最短路径——Dijkstra算法和Floyd算法

    [转]最短路径--Dijkstra算法和Floyd算法 标签(空格分隔): 算法 本文是转载,原文在:最短路径-Dijkstra算法和Floyd算法 注意:以下代码 只是描述思路,没有测试过!! Di ...

  6. 最短路径—Dijkstra算法和Floyd算法

    原文链接:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最后边附有我根据文中Dijkstra算法的描述使用jav ...

  7. 最短路径—大话Dijkstra算法和Floyd算法

    Dijkstra算法 算法描述 1)算法思想:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , ...

  8. 最短路径—Dijkstra算法和Floyd算法【转】

    本文来自博客园的文章:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html Dijkstra算法 1.定义概览 Dijk ...

  9. 【转载】最短路径—Dijkstra算法和Floyd算法

    注意:以下代码 只是描述思路,没有测试过!! Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始 ...

随机推荐

  1. 使用Spring Data JPA进行数据分页与排序

    一.导读 如果一次性加载成千上万的列表数据,在网页上显示将十分的耗时,用户体验不好.所以处理较大数据查询结果展现的时候,分页查询是必不可少的.分页查询必然伴随着一定的排序规则,否则分页数据的状态很难控 ...

  2. Java 方法重载 (Overload)

    对重载 (Overload) 的认识 为什么要用方法重载: 对于功能类似的方法来说,因为参数列表不一样,如果定义不同名称的方法,太麻烦且难以记忆. 为了解决这个问题,引入方法的重载. 重载的定义: 多 ...

  3. python3 自己写的一个小算法(比对中文文本相似度)

    函数使用说明: 函数的三个参数分别是“匹配语句”,“匹配语料”,“相关度”: 匹配语句,和匹配预料中的语句匹配的语句,必须为字符串: 匹配语料,被匹配语句来匹配的语句列表,必须为列表: 相关度,函数只 ...

  4. 《Effective Java》 读书笔记(二) 在构造参数过多的时候优先考虑使用构造器

    刚开始看见这个标题的时候,我想到了python可以选择初始化参数的语法,C++.C#能有默认参数. 为什么Java什么都没有~~ 好吧,我们是使用构造器来实现它. 1.当一个类的构造函数需要很多构造函 ...

  5. deepin扬声器/耳机没有声音解决方案

    昨天准备在deepin系统下看视频学习一下Linux,结果登入deepin系统后发现不论是外放还是插耳机竟然都没有声音,这种情况以前也出现过,只不过没有在意,后来就自己又好了,今天这次可真是让我决定要 ...

  6. MIT线性代数:18.行列式及其特性

  7. My Eclipse 配置

    设置编码格式 点击Windows → preference → WorkSpace 设置编码格式 点击Windows → preference → General →Appearence → Colo ...

  8. 深度解密Go语言之 pprof

    目录 什么是 pprof pprof 的作用 pprof 如何使用 runtime/pprof net/http/pprof pprof 进阶 Russ Cox 实战 查找内存泄露 总结 参考资料 相 ...

  9. salesforce lightning零基础学习(十四) Toast 浅入浅出

    本篇参考: https://developer.salesforce.com/docs/component-library/bundle/force:showToast/specification h ...

  10. html5 微信真机调试方法vConsole

    html5 微信真机调试方法 vConsolehttps://blog.csdn.net/weixin_36934930/article/details/79870240