图——图的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> ...
随机推荐
- LDA主题模型评估方法–Perplexity
在LDA主题模型之后,需要对模型的好坏进行评估,以此依据,判断改进的参数或者算法的建模能力. Blei先生在论文<Latent Dirichlet Allocation>实验中用的是Per ...
- linux安装篇之mongodb安装及服务自启动配置
1. 下载地址:https://www.mongodb.com/download-center?jmp=nav#community 2.放置到/opt目录下 3.解压:tar -zxvf mongod ...
- sql 查询 某字段是否重复
select count(*) from ( select * from 客户 )C GROUP BY 客户编码 select * from ( select count(*)num from ( s ...
- 洛谷 P1140 相似基因 ( 线性DP || 类LCS )
题意 : 题目链接 分析 : 可以观察到给出的配对代价表中对角线部分是正数 其余的都是负数,也就是说让相同字母的匹配的越多越好 即找出 LCS 但是这里 DP 的过程需要记录一下代价 有关 LCS ...
- #381 Div2 Problem C Alyona and mex (思维 && 构造)
题意 : 题目的要求是构造出一个长度为 n 的数列, 构造条件是在接下来给出的 m 个子区间中, 要求每一个子区间的mex值最大, 然后在这 m 个子区间产生的mex值中取最小的输出, 并且输出构造出 ...
- android日志优先级
Android 的日志分为如下几个优先级(priority): V —— Verbose(最低,输出得最多) D —— Debug I —— Info W —— Warning E —— Error ...
- [BZOJ1030]:[JSOI2007]文本生成器(AC自动机+DP)
题目传送门 题目描述 JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群, 他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是 ...
- i++ 是线程安全的吗
相信很多中高级的 Java 面试者都遇到过这个问题,很多对这个不是很清楚的肯定是一脸蒙逼.内心肯定还在质疑,i++ 居然还有线程安全问题?只能说自己了解的不够多,自己的水平有限. 先来看下面的示例来验 ...
- mysql 数据增删改的总结
一.在MySQL管理软件中,可以通过SQL语句中的DML语言来实现数据的操作,包括 1.使用INSERT实现数据的插入2.UPDATE实现数据的更新3.使用DELETE实现数据的删除4.使用SELEC ...
- POJ 1625 Censored ( Trie图 && DP && 高精度 )
题意 : 给出 n 个单词组成的字符集 以及 p 个非法串,问你用字符集里面的单词构造长度为 m 的单词的方案数有多少种? 分析 :先构造出 Trie 图方便进行状态转移,这与在 POJ 2278 中 ...