问题描述:

最短路问题(short-path problem):若网络中的每条边都有一个数值(长度、成本、时间等),则找出两节点(通常是源节点和阱节点)之间总权和最小的路径就是最短路问题。最短路问题是网络理论解决的典型问题之一,可用来解决管路铺设、线路安装、厂区布局和设备更新等实际问题。

1.floyd算法

算法描述:

Floyd算法又称为插点法,是一种用于寻找给定的加权图中多源点之间最短路径的算法。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。

时间复杂度:O(n^3)  空间复杂度:O(n^2)

可以看下这篇文章,讲得非常清楚:http://blog.chinaunix.net/uid-26548237-id-3834873.html

下面就讲下我对这个算法的理解:

首先这个算法能做的事,就是寻找给定的加权图中多源点之间最短路径

也就是这张图:

这里有N个点,互相之间的路径长度不一,怎么求其中任意两点的最短路径。

floyd算法的思路就是从比较入手,比较两点直接连通和隔一个点连通的长度。

从v0开始,遍历任意两个点,寻找有没有两个点通过v0的最短路径比这两点直接连通的要短。

比如v0和v2,要比较这两个点直接连通和隔一个点连通的长度。从图上可知,v0-v2的最短路径是经过v1,走0-1-2,而不是直接0-2。所以结果是经过v1比直接连通要短。

再比如v0和v4,要比较这两个点直接连通和隔一个点连通的长度,但v0和v4没有直接连通怎么办,就设v0-v4直接连通的长度是无穷大,这样不管是经过v1还是经过v2,都比直接连通的长度要短。

找到后怎么办,就把最短的长度和路径结果保存起来,以此再遍历下一个点v1,继续比较。

全部遍历一遍后,就可以得到任意两点之间的最短路径了。

具体实现如下:

 #include <iostream>
using namespace std; #define MAXVEX 20
#define MAXEDGE 20
#define INFINITY 65535 typedef struct
{
int vexs[MAXVEX];
int arc[MAXVEX][MAXVEX];
int numVertexes,numEdges;
}MGraph; typedef int Patharc[MAXVEX][MAXVEX];
typedef int ShortPathTable[MAXVEX][MAXVEX]; void CreateGraph(MGraph* G)
{
cout<<"请输入边数和顶点数:\n";
int d,n,i,j;
cin>>d>>n;
G->numVertexes = n;
G->numEdges = d; //给顶点和边初始化
for(i = ;i<G->numVertexes;i++)
G->vexs[i] = i;
for(i = ;i<G->numVertexes;i++)
{
for(j = ;j<G->numVertexes;j++)
{
if(i==j)
G->arc[i][j] = ;
else
G->arc[i][j] = G->arc[j][i] = INFINITY;
}
} G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=; G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=; G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=; G->arc[][]=; for(i = ;i<G->numVertexes;i++)
{
for(j = i;j<G->numVertexes;j++)
{
G->arc[j][i] = G->arc[i][j];
}
}
} /* Floyd算法,求网图G中各顶点v到其余顶点w的最短路径P[v][w]及带权长度D[v][w]。 */
void ShortestPath_Floyd(MGraph G, Patharc *P, ShortPathTable *D)
{
int v,w,k;
for(v = ;v<G.numVertexes;v++)
{
for(w = ;w<G.numVertexes;w++)
{
(*P)[v][w] = w;
/* 初始化P */
(*D)[v][w] = G.arc[v][w];
/* D[v][w]值即为对应点间的权值 */
} }
for(k = ;k<G.numVertexes;k++)
{
for(v = ;v<G.numVertexes;v++)
{
for(w = ;w<G.numVertexes;w++)
{
if((*D)[v][w]>(*D)[v][k]+(*D)[k][w])
{
(*D)[v][w] = (*D)[v][k]+(*D)[k][w];
(*P)[v][w] = (*P)[v][k];
} } }
} } int main()
{
int v,w,k=-; MGraph G; Patharc P;
ShortPathTable D; CreateGraph(&G); ShortestPath_Floyd(G,&P,&D); cout<<"各区间最短路径如下:\n";
for(v = ;v<G.numVertexes;v++)
{
for(w = v+;w<G.numVertexes;w++)
{
cout<<"v"<<v<<"-v"<<w<<" weight: "<<D[v][w];
k = P[v][w];
cout<<" path: "<<v;
while(k!=w)
{
cout<<" -> "<<k;
k = P[k][w];
}
cout<<" -> "<<w<<" "<<endl;
}
cout<<endl; } cout<<"最短路径D\n"; for(v=; v<G.numVertexes; ++v)
{
for(w=; w<G.numVertexes; ++w)
{
cout<<D[v][w]<<" ";
}
cout<<endl;
} cout<<"最短路径P\n"; for(v=; v<G.numVertexes; ++v)
{
for(w=; w<G.numVertexes; ++w)
{
cout<<P[v][w]<<" ";
}
cout<<endl;
} return ; }

算法优化:

floyd(权值非负)适用于有向图和无向图

1 floyd 的思想就是通过枚举n个点利用DP的思想来更新最短距离的,假设当前枚举到第k个点,那么就有任意的两个点i , j ,如果i k 相连 j k 相连 那么就可以知道这个时候dis[i][j] = min(dis[i][j] , dis[i][k] + dis[k][j]);,那么只要枚举完n个点,那么就说明已经完全更新完所有两点直间的最短路。

2 floyd算法是最简单的最短路径的算法,可以计算图中任意两点间的最短路径。floyd算法的时间复杂度为o(n^3),如果是一个没有边权的图,把相连的两点间的距离设为dis[i][j]=1.不相连的两点设为无穷大,用floyd算法可以判断i j两点是否相连。
3 floyd 算法不允许所有的权值为负的回路。可以求出任意两点之间的最短距离。处理的是无向图
4 缺点是时间复杂度比较高,不适合计算大量数据

5 如果dis[i][i] != 0,说明此时存在环。

6 如果利用floyd求最小值的时候,初始化dis为INF , 如果是求最大值的话初始化为-1.

最短路问题(floyd算法)(优化待续)的更多相关文章

  1. HDU 2066 最短路floyd算法+优化

    http://acm.hdu.edu.cn/showproblem.php?pid=206 题意 从任意一个邻居家出发 到达任意一个终点的 最小距离 解析 求多源最短路 我想到的是Floyd算法 但是 ...

  2. 最短路问题(dijkstral 算法)(优化待续)

    迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以起始点为中心向 ...

  3. Floyd算法解决多源最短路问题

    说好的写dijkstra 算法堆优化版本的,但是因为,妹子需要,我还是先把Floyd算法写一下吧!啦啦啦! 咳咳,还是说正事吧! ----------------------------------- ...

  4. Floyd算法 解决多元汇最短路问题

    接下来是图论问题求解最短路问题的最后一个,求解多元汇最短路问题 我们之前一般都是问1-n的最短路径,这里我们要能随便去问i到j的最短路径: 这里介绍一下Floyd算法:我们只有一个d[maxn][ma ...

  5. 图论——Floyd算法拓展及其动规本质

    一.Floyd算法本质 首先,关于Floyd算法: Floyd-Warshall算法是一种在具有正或负边缘权重(但没有负周期)的加权图中找到最短路径的算法.算法的单个执行将找到所有顶点对之间的最短路径 ...

  6. 图论算法(二)最短路算法:Floyd算法!

    最短路算法(一) 最短路算法有三种形态:Floyd算法,Shortset Path Fast Algorithm(SPFA)算法,Dijkstra算法. 我个人打算分三次把这三个算法介绍完. (毕竟写 ...

  7. 最短路-SPFA算法&Floyd算法

    SPFA算法 算法复杂度 SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环. SPFA一般情况复杂度是O(m)最坏情况下复杂度和朴素 ...

  8. floyd算法小结

    floyd算法是被大家熟知的最短路算法之一,利用动态规划的思想,f[i][j]记录i到j之间的最短距离,时间复杂度为O(n^3),虽然时间复杂度较高,但是由于可以处理其他相似的问题,有着广泛的应用,这 ...

  9. SPFA和FLOYD算法如何打印路径

    早晨碰到了一题挺裸的最短路问题需要打印路径:vijos1635 1.首先说说spfa的方法: 其实自己之前打的最多的spfa是在网格上的那种,也就是二维的 一维的需要邻接表+queue 以及对于que ...

随机推荐

  1. Java8新特性学习笔记(一) Lambda表达式

    没有用Lambda表达式的写法: Comparator<Transaction> byYear = new Comparator<Transaction>() { @Overr ...

  2. mxonline实战14,全局搜索,修改个人中心页面个人资料信息

    对应github地址:第14天   一. 全局搜索   1. 使用关键词搜索 courses/views.py/CourseListView新增代码,不用把search_keywords传到前端

  3. html中object和embed标签的区别

    ♦object定义一个嵌入的对象.请使用此元素向您的 XHTML 页面添加多媒体.此元素允许您规定插入 HTML 文档中的对象的数据和参数,以及可用来显示和操作数据的代码. ♦<object&g ...

  4. hive连接mysql遇到的问题

    启动hive之前应该先启动metastore,也是在bin目录下:./hive --service metastore &然后再启动hive: ./hive 今天连接hive时总是报错:Una ...

  5. 编译原理(六)自底向上分析之LR分析法

    自底向上分析之LR分析法 说明:以老师PPT为标准,借鉴部分教材内容,AlvinZH学习笔记. 基本概念 1. LR分析:从左到右扫描(L)自底向上进行规约(R),是规范规约,也即最右推导(规范推导) ...

  6. FCN详解

    转载自:https://www.cnblogs.com/gujianhan/p/6030639.html 论文地址:https://arxiv.org/pdf/1411.4038v1.pdf 背景 C ...

  7. jQuery css()与class()的用法

    一.css()用法:   1.设置css // css(name, value) // 修改单个样式 // name:样式名 value:样式值 $("li") .css(&quo ...

  8. 4. C++11非受限联合体

    在C/C++中,联合体是一种构造类型的数据结构.在一个联合体内,我们可以定义多种不同的数据类型,这些数据类型共享相同的内存空间,可以达到节省内存空间的目的. 1. 取消数据类型的限制 在C++98中, ...

  9. Camera Sensor

    camera sensor分为YUV sensor和Bayer sensor. YUV Sensor YUV Sensor输出的格式是YUV,图像的处理效果使用sensor内部的ISP,BB端接收到的 ...

  10. MNIST手写数字识别 Tensorflow实现

    def conv2d(x, W): return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME') 1. strides在官方定义中是一 ...