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法最短路径实现的更多相关文章

  1. c/c++ 图的创建及图的相关函数(链表法)

    c/c++ 图的创建及图的相关函数(链表法) 图的概念 图由点和线组成 知道了图中有多少个点,和哪些点之间有线,就可以把一张图描绘出来 点之间的线,分有方向和无方向 创建图 创建图,实际就是创建出节点 ...

  2. Floyd-Warshall求图中任意两点的最短路径

    原创 除了DFS和BFS求图中最短路径的方法,算法Floyd-Warshall也可以求图中任意两点的最短路径. 从图中任取两点A.B,A到B的最短路径无非只有两种情况: 1:A直接到B这条路径即是最短 ...

  3. 图——图的Dijkstra法最短路径实现

    1,最短路径的概念: 1,从有向图中某一顶点(起始顶点)到达另一顶点(终止顶点)的路径中,其权值之和最小的路径: 2,问题的提法: 1,给定一个带权有向图 G 与起始顶点 v,求从 v 到 G 中其它 ...

  4. 图——图的Prim法最小生成树实现

    1,运营商的挑战: 1,在下图标出的城市间架设一条通信线路: 2,要求: 1,任意两个城市间都能够通信: 2,将架设成本降至最低: 2,问题抽象: 1,如何在图中选择 n - 1 条边使得 n 个顶点 ...

  5. 洛谷 P7516 - [省选联考 2021 A/B 卷] 图函数(Floyd)

    洛谷题面传送门 一道需要发现一些简单的性质的中档题(不过可能这道题放在省选 D1T3 中偏简单了?) u1s1 现在已经是 \(1\text{s}\)​ \(10^9\)​ 的时代了吗?落伍了落伍了/ ...

  6. 最短路径(Floyd法)

    最短路径法: 算法的主要思想是:单独一条边的路径也不一定是最佳路径. 从任意一条单边路径开始.所有两点之间的距离是边的权的和,(如果两点之间没有边相连, 则为无穷大). 对于每一对顶点 u 和 v,看 ...

  7. 图——图的Kruskal法最小生成树实现

    1,最小生成树的特征: 1,选取的边是图中权值较小的边: 2,所有边连接后不构成回路: 2,prim 算法是以顶点为核心的,最下生成树最大的特征是边,但 prim 算法非要以顶点为核心来进行,有些复杂 ...

  8. 图-图的表示、搜索算法及其Java实现

    1.图的表示方法 图:G=(V,E),V代表节点,E代表边. 图有两种表示方法:邻接链表和邻接矩阵 邻接链表因为在表示稀疏图(边的条数|E|远远小于|V|²的图)时非常紧凑而成为通常的选择. 如果需要 ...

  9. 15 图-图的遍历-基于邻接矩阵实现的BFS与DFS算法

    算法分析和具体步骤解说直接写在代码注释上了 TvT 没时间了等下还要去洗衣服 就先不赘述了 有不明白的欢迎留言交流!(估计是没人看的了) 直接上代码: #include<stdio.h> ...

随机推荐

  1. 对js库的调研研究------引用

    1. 引言 从以下几个方面来阐述这个问题: 特性. 稳定性. 性能. 包生态. 社区. 学习曲线. 文档. 工具. 发展历史. 团队. 兼容性. 趋势. 2.概述 & 精读 特性 当你调研一个 ...

  2. mybatis config 配置设置说明

    <!– 配置设置 –> 2.           <settings> 3.               <!– 配置全局性 cache 的 ( 开 / 关) defau ...

  3. codevs 1057 津津的储蓄计划 2004年NOIP全国联赛提高组 x

     时间限制: 1 s  空间限制: 128000 KB   题目描述 Description 津津的零花钱一直都是自己管理.每个月的月初妈妈给津津300元钱,津津会预算这个月的花销,并且总能做到实际花 ...

  4. WebStorm 在 Mac 版本的基本设置,包括 ES6、Node.js、字体大小等

    WebStorm 在 Mac 和 win 的设置有区别,便于以后用到快速查找,记之. 要设置先点击 WebStorm 字样如下图: 后点击 Preferences 字样如下图: 设置 es6 语法, ...

  5. 7.Python编码规范(PEP 8)

    在讲解具体的 Python 编码规范之前,先来看看图 1 中的代码: 图 1 两段功能相同的 Python 代码 对比图 1 中的两段代码你会发现,它们所包含的代码时完全相同的,但很明显,右侧的代码编 ...

  6. SPFA算法的SLF优化 ——loj#10081. 「一本通 3.2 练习 7」道路和航线

    今天做到一道最短路的题,原题https://loj.ac/problem/10081 题目大意为给一张有n个顶点的图,点与点之间有m1条道路,m2条航线,道路是双向的,且权值非负,而航线是单向的,权值 ...

  7. Mysql中 BLOB字段转String的方法

    转:https://www.cnblogs.com/renjie0520/p/5242350.html 1.通过sql直接转换 select CONVERT (*** USING utf8) AS u ...

  8. 程序员心髓:移动应用API设计10大技巧

    移动App与基于Web/云服务发生对话是很常见的事情,最简单的可能仅仅只是检索数据,但也可能包含发送数据.用户授权和管理.而这也就验证了为移动应用建立API的重要性,为此,我们特总结了10大移动API ...

  9. 系统性能信息模块--psutil

    #安装psutil模块#pip install psutil -i https://pypi.doubanio.com/simple #导入psutil模块import psutilimport da ...

  10. 洛谷P4095新背包问题

    传送 这道题最最暴力的方法就是对于每一个询问都跑一边多重背包问题,但显然q不会那么友好的让我们用暴力过掉这道题. 考虑优化.我们可以先把裸的多重背包搞成二进制优化后的多重背包.但是复杂度依然无法接受. ...