图——图的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> ...
随机推荐
- 【leetcode】LCP 3. Programmable Robot
题目如下: 力扣团队买了一个可编程机器人,机器人初始位置在原点(0, 0).小伙伴事先给机器人输入一串指令command,机器人就会无限循环这条指令的步骤进行移动.指令有两种: U: 向y轴正方向移动 ...
- CondaHTTPError问题的解决
我是在配置pytorch时遇到的这个错误,截图如下: 这是某个网址访问失败导致的,我们可以通过添加其他路径解决这个问题,分别添加如下4个镜像路径,解决问题: 1)conda config --add ...
- pycharm的个性化设置
1. 调整背景颜色 file -- settings -- Editor -- Color Scheme 2. 调整字体.字号.行间距 file -- settings -- Editor -- Fo ...
- Qt 静态库与共享库(动态库)共享配置的一个小办法
对于用 QtCreator 编写静态库,动态库,如何能够以最小的改动, 方便的实现两种形式的库文件生成:可以这麽做: 1)使用想到建立静态库 2)在项目配置文件*.pro 中: TARGET = n ...
- Json和XML的一些差别
XML: 扩展标记语言,可以用来标记数据.定义数据类型, 优缺点: 1.格式统一,符合标准: 2.容易与其他系统进行远程交互,数据共享比较方便 3.XML文件庞大,文件格式复杂,传输占带宽,较复杂 J ...
- 大哥带的Orchel数据库的盲注入bool型
0X01判断闭合 ?username=SMITH' 错误 ?username=SMITH'' 正确 ?username=SMITH' and ascii(substr((select user fro ...
- 读读《编写高质量代码:改善Java程序的151条建议》
这本书可以作为平时写代码的一个参考书,这本书以我个人读的经验看来,最好是通过平时代码驱动的方式来读,这样吸收的快,也读的快. 这本书主要讲什么,我自己用了个思维导图概述: 根据这种导图可知,主要讲的就 ...
- REST framework 之 分页
DRF分页组件 为什么要使用分页 我们数据表中可能会有成千上万条数据,当我们访问某张表的所有数据时,我们不太可能需要一次把所有的数据都展示出来,因为数据量很大,对服务端的内存压力比较大还有就是网络传输 ...
- 当出现no changes added to commit时如何正确使用git提交命令
对于这个问题,最好的解决方法就是按如下步骤:1.到根目录下:git add . :("."是必须要的)2.git commit -m "some word"3 ...
- jenkins不展示set Build Description Setter插件
问题描述: 1.jenkins 已下载 set build descripteion ,并且配置过,可以在构建历史中展示就用二维码 2.问题:构建历史中不展示二维码了,如图: 总是排查: 1.首先想到 ...