图——图的Floyd法最短路径实现
1,Dijkstra 算法一次性求得起始顶点到所有其它顶点的最短路径,如果想要求解任意两个顶点之间的最短路径,可将图中顶点作为起始顶点执行 n 次 Dijkstra 算法就可以了;
2,可能解决方案:
1,算法执行结束后,i 到 j 最短路径值存储于 dist[i][j] 中。最短路径前驱结点存储于 path[N][N] 中;
2,这种方法比较土;
3,问题的提法:
1,已知一个各边权值均大于 0 的带权有向图,对每一对顶点 vi != vj,求出 vi 与 vj 之间的最短路径值以及最短路径上的顶点;
4,Floyd 算法核心:
1,定义一个 n 阶方阵序列:
其中:
2,怀疑当前两个顶点间路径不是最短路径,因此 Floyd 算法尝试通过其他顶点中转、直到找到一个中转点的中转路径最短;
5,n 阶方阵中元素的意义:
1,都是由邻接方阵中的权值推得的;
2,此算法是通过递推的方式得到两个顶点间最短路径的;
3,把所有的顶点的中转路径都推导完了,也就得到最小路径了;
4,后面方阵的推导,包含着前面方阵的信息,且每次推导都是最小,直到推导了全部顶点,得到最终最短路径;
6,Floyd 算法精髓:
7,Floyd 算法的实现:
1,初始化:
1,本质:使用邻接矩阵初始化 A(-1);
2,A(0), ..., A(n-1) 矩阵推导:
1,本质:使用中转顶点逐步推导最短路径;
2,最外层是在说 A(k)矩阵的循环,循环推导完后,得到最短路径矩阵 A(n-1),即为所求;
8,如何记录最短路径上的各个顶点?
1,定义辅助矩阵:
1,int path[N][N]; // 路径矩阵
1,path[i][j] 表示 i 到 j 的路径上所经过的第 1 个顶点;
2,初始化:path[i][j] = -1; or paht[i][j] = j;
1,有直接的连接则设置为 j,表示经过的第一个顶点为终值顶点 j;
2,没有连接的两个顶点设置为 -1;
3,修改:
if( (dist[i][k] + dist[k][j]) < dist[i][j] )
{
dist[i][j] = dist[i][k] + dist[k][j];
path[i][j] = paht[i][k];
}
1,if 条件为真,由 k 这个顶点中转可以得到一条更短路径,则由 i 到 j 这条路径上所经过的第一个顶点就是由 i 到 k 这条路径上经过的第一个顶点,因为由 k 中转了下;
2,路径矩阵示例:
1,由一个点的路径推至其它路径:
2,辅助矩阵和路径:
9,Floyd 最短路径算法实现:
/* floyd 每对结点之间最短路径算法,返回值为最短路径;核心为通过中转顶点寻找更短路径 */
SharedPointer< Array<int> > floyd(int x, int y, const E& LIMIT) // O(n*n*n)
{
LinkQueue<int> ret; if( ( <= x) && (x < vCount()) && ( <= y) && (y < vCount()) ) //顶点编号要合理
{
DynamicArray< DynamicArray<E> > dist(vCount()); // 定义二维数组,N*N DynamicArray< DynamicArray<int> > path(vCount()); // 最短路径的辅助数组 /* 定义二维数组 */
for(int k=; k<vCount(); k++)
{
dist[k].resize(vCount());
path[k].resize(vCount());
} /* 初始值设置 */
for(int i=; i<vCount(); i++)
{
for(int j=; j<vCount(); j++)
{
path[i][j] = -; // i 和 j 是没有边的 dist[i][j] = isAdjacent(i, j) ? (path[i][j]=j, getEdge(i, j)) : LIMIT; // 邻接了就设置,利用了逗号表达式,逗号表达式第一个参数是设置顶点,第二个是设置权值
}
} /* 推导最短路径矩阵 */
for(int k=; k<vCount(); k++)
{
for(int i=; i<vCount(); i++)
{
for(int j=; j<vCount(); j++)
{
/* 推导规则,用中间顶点中转数据,看是否有最短路径值 */
if( (dist[i][k] + dist[k][j]) < dist[i][j] )
{
dist[i][j] = dist[i][k] + dist[k][j]; // 如果得到最短路径,认为其可能是最短路径,要更新其值 path[i][j] = path[i][k]; // 通过 k 顶点可以找到最小值,则这个顶点找到了
}
}
}
} while( (x != -) && (x != y) ) // 推导到终止顶点为止
{
ret.add(x); // 最短路径上的各个顶点加到返回值中 x = path[x][y]; // 递归的将 path[x][y] 上经过的第一个顶点放入 x 中,然后在下一个递推中从 x 出发再递归处其它顶点;
} if( x != - )
{
ret.add(x); // 将最后的一个 x 加入返回值队列中,因为上面 x == y,终止了在返回队列中的加入,所以这里要加入
}
}
else
{
THROW_EXCEPTION(InvalidParameterException, "Index <x, y> is invalid ...");
} /* 看看目标的两个最短值之间是否真的有最短路径 */
if( ret.length() < )
{
THROW_EXCEPTION(ArithmeticException, "There is no path from x to y ...");
} return toArray(ret);
}
10,小结:
1,Floyd 算法通过递推逐步求得所有顶点间的最短路径;
2,Floyd 算法的本质是通过中转顶点寻找更短的路径;
3,邻接矩阵是最短路径推导的起始矩阵;
4,路径矩阵记录了最短路径上的各个顶点;
图——图的Floyd法最短路径实现的更多相关文章
- c/c++ 图的创建及图的相关函数(链表法)
c/c++ 图的创建及图的相关函数(链表法) 图的概念 图由点和线组成 知道了图中有多少个点,和哪些点之间有线,就可以把一张图描绘出来 点之间的线,分有方向和无方向 创建图 创建图,实际就是创建出节点 ...
- Floyd-Warshall求图中任意两点的最短路径
原创 除了DFS和BFS求图中最短路径的方法,算法Floyd-Warshall也可以求图中任意两点的最短路径. 从图中任取两点A.B,A到B的最短路径无非只有两种情况: 1:A直接到B这条路径即是最短 ...
- 图——图的Dijkstra法最短路径实现
1,最短路径的概念: 1,从有向图中某一顶点(起始顶点)到达另一顶点(终止顶点)的路径中,其权值之和最小的路径: 2,问题的提法: 1,给定一个带权有向图 G 与起始顶点 v,求从 v 到 G 中其它 ...
- 图——图的Prim法最小生成树实现
1,运营商的挑战: 1,在下图标出的城市间架设一条通信线路: 2,要求: 1,任意两个城市间都能够通信: 2,将架设成本降至最低: 2,问题抽象: 1,如何在图中选择 n - 1 条边使得 n 个顶点 ...
- 洛谷 P7516 - [省选联考 2021 A/B 卷] 图函数(Floyd)
洛谷题面传送门 一道需要发现一些简单的性质的中档题(不过可能这道题放在省选 D1T3 中偏简单了?) u1s1 现在已经是 \(1\text{s}\) \(10^9\) 的时代了吗?落伍了落伍了/ ...
- 最短路径(Floyd法)
最短路径法: 算法的主要思想是:单独一条边的路径也不一定是最佳路径. 从任意一条单边路径开始.所有两点之间的距离是边的权的和,(如果两点之间没有边相连, 则为无穷大). 对于每一对顶点 u 和 v,看 ...
- 图——图的Kruskal法最小生成树实现
1,最小生成树的特征: 1,选取的边是图中权值较小的边: 2,所有边连接后不构成回路: 2,prim 算法是以顶点为核心的,最下生成树最大的特征是边,但 prim 算法非要以顶点为核心来进行,有些复杂 ...
- 图-图的表示、搜索算法及其Java实现
1.图的表示方法 图:G=(V,E),V代表节点,E代表边. 图有两种表示方法:邻接链表和邻接矩阵 邻接链表因为在表示稀疏图(边的条数|E|远远小于|V|²的图)时非常紧凑而成为通常的选择. 如果需要 ...
- 15 图-图的遍历-基于邻接矩阵实现的BFS与DFS算法
算法分析和具体步骤解说直接写在代码注释上了 TvT 没时间了等下还要去洗衣服 就先不赘述了 有不明白的欢迎留言交流!(估计是没人看的了) 直接上代码: #include<stdio.h> ...
随机推荐
- 【NOIP2016提高A组集训第1场10.29】完美标号
题目 给定M个二元组(A_i, B_i),求X_1, ..., X_N满足:对于任意(A_i, B_i),有|X_{A_i} - X_{B_i}| = 1成立. 分析 显然,对于二元组(x,y),X_ ...
- Hadoop2.7.4 yarn(HA)集群搭建步骤(CentOS7)
群节点分配: Park01:Zookeeper.NameNode(active).ResourceManager(active) Park02:Zookeeper.NameNode(standby) ...
- 【leetcode】1200. Minimum Absolute Difference
题目如下: Given an array of distinct integers arr, find all pairs of elements with the minimum absolute ...
- 使用swagger生成API说明文档
使用swagger生成API说明文档本文由个人总结,如需转载使用请标明原著及原文地址没有导出!!!!!不要整天给我留言导出呢,那个是你们百度的时候下面的推荐文章带的关键字,要做导出从swagger取数 ...
- 选择vim编辑器的7个理由
当我刚刚开始用 vi 文本编辑器的时候,我讨厌它!我认为这是有史以来设计上最痛苦和反人类的编辑器.但我还是决定我必须学会它,因为如果你使用的是 Unix,vi 无处不在并且是唯一一个保证你可以使用的编 ...
- 容器适配器————priority_queue
#include <queue> priority_queue 容器适配器定义了一个元素有序排列的队列.默认队列头部的元素优先级最高.因为它是一个队列,所以只能访问第一个元素,这也意味着优 ...
- java生成二维码学习笔记
纠错等级: QRErrorCorrectLevel.L 7%的字码可被修正 QRErrorCorrectLevel.M 15%的字码可被修正 QRErrorCorrectLevel.Q 25%的字码可 ...
- 阶段3 1.Mybatis_04.自定义Mybatis框架基于注解开发_2 回顾自定义mybatis的流程分析
- Jmeter之插件安装
在实际工作中,会用到一些额外的jmeter插件,现在描述其插件的安装. 一.下载plugins-manager.jar 在官网中下载plugins-manger.jar,方便后续其他插件的安装,下载地 ...
- vs2010发布网站时有些文件没有发布出去的解决办法。
项目中包含了一些ttf字体文件做为图标使用,可是发布时发现生成的目录中没有这个文件,这种情况这么设置一下就可以解决: 1,在文件上点击右键,选择“属性”. 2,在弹出的属性窗口中,更改“生成操作”为“ ...