Floyd算法(原理|代码实现)
http://www.cnblogs.com/twjcnblog/archive/2011/09/07/2170306.html
正如我们所知道的,Floyd算法用于求最短路径。Floyd算法可以说是Warshall算法的扩展,三个for循环就可以解决问题,所以它的时间复杂度为O(n^3)。
Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个节点X到B。所以,我们假设Dis(AB)为节点A到节点B的最短路径的距离,对于每一个节点X,我们检查Dis(AX) + Dis(XB) < Dis(AB)是否成立,如果成立,证明从A到X再到B的路径比A直接到B的路径短,我们便设置Dis(AB) = Dis(AX)
+ Dis(XB),这样一来,当我们遍历完所有节点X,Dis(AB)中记录的便是A到B的最短路径的距离。
很简单吧,代码看起来可能像下面这样:
for (int i{ for (int j { for (int k { if ( { // Dis[i][j] } } }} |
但是这里我们要注意循环的嵌套顺序,如果把检查所有节点X放在最内层,那么结果将是不正确的,为什么呢?因为这样便过早的把i到j的最短路径确定下来了,而当后面存在更短的路径时,已经不再会更新了。
让我们来看一个例子,看下图:

图中红色的数字代表边的权重。如果我们在最内层检查所有节点X,那么对于A->B,我们只能发现一条路径,就是A->B,路径距离为9。而这显然是不正确的,真实的最短路径是A->D->C->B,路径距离为6。造成错误的原因就是我们把检查所有节点X放在最内层,造成过早的把A到B的最短路径确定下来了,当确定A->B的最短路径时Dis(AC)尚未被计算。所以,我们需要改写循环顺序,如下:
for (int k{ for (int i { for (int j { if ( { // Dis[i][j] } } }} |
这样一来,对于每一个节点X,我们都会把所有的i到j处理完毕后才继续检查下一个节点。
那么接下来的问题就是,我们如何找出最短路径呢?这里需要借助一个辅助数组Path,它是这样使用的:Path(AB)的值如果为P,则表示A节点到B节点的最短路径是A->...->P->B。这样一来,假设我们要找A->B的最短路径,那么就依次查找,假设Path(AB)的值为P,那么接着查找Path(AP),假设Path(AP)的值为L,那么接着查找Path(AL),假设Path(AL)的值为A,则查找结束,最短路径为A->L->P->B。
那么,如何填充Path的值呢?很简单,当我们发现Dis(AX) + Dis(XB) < Dis(AB)成立时,就要把最短路径改为A->...->X->...->B,而此时,Path(XB)的值是已知的,所以,Path(AB) = Path(XB)。
好了,基本的介绍完成了,接下来就是实现的时候了,这里我们使用图以及邻接矩阵:
#define#define//////////////////////////////////////////////////////////////////////////struct Graph{ int arrArcs[MAX_VERTEX_COUNT][MAX_VERTEX_COUNT]; // int nVertexCount; // int nArcCount; //};////////////////////////////////////////////////////////////////////////// |
首先,我们写一个方法,用于读入图的数据:
void readGraphData({ std::cout"请输入顶点数量和边的数量:; std::cin std::cin std::cout"请输入邻接矩阵数据:" << for (int row { for (int col { std::cin } }} |
接着,就是核心的Floyd算法:
void floyd(int _arrDis[][MAX_VERTEX_COUNT],int _arrPath[][MAX_VERTEX_COUNT],int _nVertexCount{ // for (int i { for (int j { _arrPath[i][j] } } ////////////////////////////////////////////////////////////////////////// for (int k { for (int i { for (int j { if ( { // _arrDis[i][j] _arrPath[i][j] } } } }} |
OK,最后是输出结果数据代码:
void printResult(int _arrDis[][MAX_VERTEX_COUNT],int _arrPath[][MAX_VERTEX_COUNT],int _nVertexCount{ std::cout"Origin << for (int i { for (int j { if (// { std::cout" <<"\t\t"; if (// { std::cout"INFINITE" <<"\t\t"; } else { std::cout"\t\t"; // // std::stack<int> int k do { k stackVertices.push( }while ( ////////////////////////////////////////////////////////////////////////// std::cout stackVertices.pop(); unsignedint nLength for (int nIndex { std::cout" << stackVertices.pop(); } std::cout" << } } } }} |
好了,是时候测试了,我们用的图如下:

测试代码如下:
int main(void ){ Graph readGraphData( ////////////////////////////////////////////////////////////////////////// int arrDis[MAX_VERTEX_COUNT][MAX_VERTEX_COUNT]; int arrPath[MAX_VERTEX_COUNT][MAX_VERTEX_COUNT]; // for (int i { for (int j { arrDis[i][j] } } floyd( ////////////////////////////////////////////////////////////////////////// printResult( ////////////////////////////////////////////////////////////////////////// system("pause" ); return 0;} |
如图:

版权声明:本文为博主原创文章,未经博主允许不得转载。
Floyd算法(原理|代码实现)的更多相关文章
- Floyd算法核心代码证明
Flody 大家都知道这个最终模版: for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dis[i ...
- 最短路-SPFA算法&Floyd算法
SPFA算法 算法复杂度 SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环. SPFA一般情况复杂度是O(m)最坏情况下复杂度和朴素 ...
- 最短路径(Floyd算法)
声明:图片及内容基于https://www.bilibili.com/video/BV1oa4y1e7Qt?from=articleDetail 多源最短路径的引入 Floyd算法 原理 加入a: 加 ...
- (poj 3660) Cow Contest (floyd算法+传递闭包)
题目链接:http://poj.org/problem?id=3660 Description N ( ≤ N ≤ ) cows, conveniently numbered ..N, are par ...
- HDOJ 1217 Arbitrage(拟最短路,floyd算法)
Arbitrage Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...
- Floyd算法简单实现(C++)
图的最短路径问题主要包括三种算法: (1)Dijkstra (没有负权边的单源最短路径) (2)Floyed (多源最短路径) (3)Bellman (含有负权边的单源最短路径) 本文主要讲使用C++ ...
- 图的最短路径算法-- Floyd算法
Floyd算法求的是图的任意两点之间的最短距离 下面是Floyd算法的代码实现模板: ; ; // maxv为最大顶点数 int n, m; // n 为顶点数,m为边数 int dis[maxv][ ...
- Logistic回归分类算法原理分析与代码实现
前言 本文将介绍机器学习分类算法中的Logistic回归分类算法并给出伪代码,Python代码实现. (说明:从本文开始,将接触到最优化算法相关的学习.旨在将这些最优化的算法用于训练出一个非线性的函数 ...
- AC-BM算法原理与代码实现(模式匹配)
AC-BM算法原理与代码实现(模式匹配) AC-BM算法将待匹配的字符串集合转换为一个类似于Aho-Corasick算法的树状有限状态自动机,但构建时不是基于字符串的后缀而是前缀.匹配 时,采取自后向 ...
随机推荐
- PHP实现验证码功能
原文链接:http://www.qqdeveloper.com/a/54.html 什么是验证码? 借用百度的解释:验证码这个词最早是在2002年由卡内基梅隆大学的路易斯·冯·安.Manuel Blu ...
- 【Keil】Keil5-改变字的大小和颜色
点击 Edit / Configuration 出现弹窗,选择Colors & Fonts 底下可以选择要改哪个部分,例如普通代码.数字.关键字.注释...等等,当然也可以改变背景颜色的,英文 ...
- git提交代码速度过慢解决方法(macos)
iterm2中ping下github.com和github.global.ssl.fastly.net $ ping github.com 得到以下 PING github.com (192.30.2 ...
- Python3 urllib 爬取 花瓣网图片
点我去我的github上看源码 **花瓣网是动态的,所以要抓包分析,,但我真的累的不行,不想写教程了,我源码里有注释
- Gulp的安装配置过程和一些小坑
谈谈gulp. 项目尾声,老师叫我去熟悉一下grunt前端自动化工具,第一次知道这种东西,我就查各种资料啊,发现grunt已经‘过时’了,大家都用gulp和webpack.我当然选择了配置最简单的gu ...
- Shell 变量简介
1. 概述 概述 知识点又稀又碎, 面试一问就流泪 简单介绍下 shell 下的变量及其基本操作 2. 环境 操作系统 CentOS Linux release 7.5 用户 root 用户 约定 使 ...
- Oracle入门第二天(上)——基本查询SQL
一.SQL概述 起源于标准不再赘述,主要分为DDL,DML,DCL 相关介绍,参考MySQL章节:http://www.cnblogs.com/jiangbei/p/6696202.html 二.基本 ...
- 20155216 实验一《Java开发环境的熟悉》实验报告
实验内容 1.使用JDK编译.运行简单的Java程序. 2.使用idea 编辑.编译.运行.调试Java程序. 3.实现四则运算,并进行测试. 4.实现带有"()"的"+ ...
- OpenCV中对Mat里面depth,dims,channels,step,data,elemSize和数据地址计算的理解
原文:OpenCV中对Mat里面depth,dims,channels,step,data,elemSize和数据地址计算的理解 Title : cv::Mat depth/dims/channels ...
- RHCSA-EXAM 模拟题目
参考答案:http://www.cnblogs.com/venicid/category/1088924.html 请首先按找以下要求配置考试系统: * Hostname: server0.examp ...