最短路径---Dijkstra/Floyd算法
1.Dijkstra算法基础:
算法过程比prim算法稍微多一点步骤,但思想确实巧妙也是贪心,目的是求某个源点到目的点的最短距离,总的来说dijkstra也就是求某个源点到目的点的最短路,求解的过程也就是求源点到整个图的最短,次短距,第三短距离等(这些距离都是源点到某个点的最短距离)。。。求出的每个距离都对应一个点,也就是要到的到这个点,求的也就是原点到所有点的最短距离,并存在二维数组中,给出目的点就能直接通过查表获得最短距离。
第1步:以源点START(假设s1)为始点,求最短距离,如何求? 与这个源点相邻的点与源点的距离全部放在一个数组dist[]中,如不可达,dist[]中为最大值,是一维数组原因是默认的是从源点到这个一维数组下标的值,只需目的点作为下标就可,这时从源点到其他点的最短的“1”条路径有了,只要选出dist[]最小的就行(得到最短路径的另一端点假设s2)。
第2步:这时要寻找源点(设s1)到另外点的次短距离,按路径长度递增次序产生各顶点最短路径,这个距离是dist[]里的值或是从第1步中选择的那个最短距离+从找到点(设s2)出发到其他点的距离(其实这里是一个更新操作更新的是dist[]里的值),如最短距离+从这点(设s2)到其他点的距离小于dist[]里面的值,就可更新dist[]数组,然后再从dist[]中选值最小的,也就是第“2”短路径(次短路径)。
第3步:寻找第“3”短路径,同上,第二短路径的端点(s3)更新与之相邻其他的点的dist[]数组里面的值。
第4步:重复上述过程n - 1次(n节点个数),得出结果,其实把源点到所有点的最短路径求出来了,都填在了dist[]表中,要找源点到哪个点的最短路,就只需要查表了。
在未选点集中选择一个最短距离最小的未选点k来扩充已选集是Dijkstra算法的关键。时间复杂度O(n^2).
void Init_Dijkstra(void)
{
count=;
for(int i=;i<MG->n;i++)
{
vis[i]=; //状态置0,表示没有求出最短路径
min_wg[i]=MG->edge[START][i]; if(min_wg[i] == INF)
min_from[i]=-; //表示到顶点i路径最短的上一个顶点不存在
else
min_from[i]=START;
} vis[START]=;
count++;
min_wg[START]=; //从源点到达源点的边权值为0
min_from[START]=START; //源点的父节点为本身
} void Dijkstra(void)
{
int min,to_index;
int new_dis; //距离更新中间值 while(count < MG->n)
{
min=INF;
to_index=-;
for(int i=;i<MG->n;i++)
if(!vis[i] && (min_wg[i] < min))
{
min=min_wg[i];
to_index=i;
} if(to_index != -)
{
// if(to_index == ENDN) //用于[2]
// break;
vis[to_index]=;
count++;
}
else
break; for(int j=;j<MG->n;j++)
if(!vis[j] && MG->edge[to_index][j] < INF)
{
new_dis=min_wg[to_index]+MG->edge[to_index][j];
if(new_dis < min_wg[j])
{
min_wg[j]=new_dis;
min_from[j]=to_index;
}
}
}
}
//查找from->to的路径
void SearchPath(int from,int to)
{
int tot=;
int index_temp; //缓存索引 path[tot++]=to;
index_temp=min_from[to];
while(index_temp != from) //回溯找到源点
{
path[tot++]=index_temp;
index_temp=min_from[index_temp];
}
path[tot]=from; printf("%c",MG->vertex[from]);
for(int i=tot-;i>=;i--) //对辅助数组进行逆向输出
printf("->%c",MG->vertex[path[i]]);
printf("\n");
}
2.Floyd算法
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的最短路径距离。
接下来如何找出最短路径?需借助辅助数组Path:同时借助[栈或队列或数组]。path[i][j] =k表示最短路径i-…j 和j的直接前驱为k,此时初始化是path[i][j]=i,即是:i-->......-->k ->j举例:如1-> 5->4 4->3->6 ,此时path[1][6]=0;0表示1->6不通。当我们引入节点k = 4此时有1->5->4->3->6,显然有paht[1][6] = 3 = paht[4][6] =paht[k][6],如是有 path[i][j] =path[k][j] 。对于1->5相邻边,我们可以在初始化时候 有 paht[1][5]=1;如是对于最短路径1->5->4->3->6有paht[1][6] = 3; paht[1][3]= 4;paht[1][4] = 5; paht[1][5] =1 如此逆推不难得到最短路径记录值。
void Init_Floyd(void)
{
for(int i=;i<MG->n;i++)
for(int j=;j<MG->n;j++)
{
if(i == j)
{
dis[i][i]=;
path[i][i]=i;
}
else
{
dis[i][j]=MG->edge[i][j];
if(dis[i][j] == INF)
path[i][j]=-;
else
path[i][j]=i; //记录j的前驱节点
}
}
}
void Floyd(void)
{
int i,j,k; for(k=;k<MG->n;k++)
{
for(i=;i<MG->n;i++)
for(j=;j<MG->n;j++)
if((dis[i][k]> && dis[i][k]<INF) && //防止加法溢出
(dis[k][j]> && dis[k][j]<INF) &&
dis[i][k] +dis[k][j] < dis[i][j])
{
dis[i][j]=dis[i][k] +dis[k][j];
path[i][j]=path[k][j]; //记录j的直接前驱k
}
}
}
// 路径查询
void SearchPath(int from,int to)
{
int min_path[MAXL],tot=;
int index_temp; //缓存索引 min_path[tot++]=to;
index_temp=path[from][to];
while(index_temp != from) //回溯找到源点
{
min_path[tot++]=index_temp;
index_temp=path[from][index_temp];
}
min_path[tot]=from; printf("%c",MG->vertex[from]); //对辅助数组进行逆向输出
for(int i=tot-;i>=;i--)
printf("->%c",MG->vertex[min_path[i]]);
}
最短路径---Dijkstra/Floyd算法的更多相关文章
- 数据结构与算法--最短路径之Floyd算法
数据结构与算法--最短路径之Floyd算法 我们知道Dijkstra算法只能解决单源最短路径问题,且要求边上的权重都是非负的.有没有办法解决任意起点到任意顶点的最短路径问题呢?如果用Dijkstra算 ...
- 最短路径-Dijkstra+Floyd+Spfa
Dijkstra算法: Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra ...
- 最短路径:Dijkstra & Floyd 算法图解,c++描述
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 最短路径问题——floyd算法
floyd算法和之前讲的bellman算法.dijkstra算法最大的不同在于它所处理的终于不再是单源问题了,floyd可以解决任何点到点之间的最短路径问题,个人觉得floyd是最简单最好用的一种算法 ...
- 最短路径 - 弗洛伊德(Floyd)算法
为了能讲明白弗洛伊德(Floyd)算法的主要思想,我们先来看最简单的案例.图7-7-12的左图是一个简单的3个顶点的连通网图. 我们先定义两个二维数组D[3][3]和P[3][3], D代表顶点与顶点 ...
- 图的最短路径---弗洛伊德(Floyd)算法浅析
算法介绍 和Dijkstra算法一样,Floyd算法也是为了解决寻找给定的加权图中顶点间最短路径的算法.不同的是,Floyd可以用来解决"多源最短路径"的问题. 算法思路 算法需要 ...
- 图论-最短路径<Dijkstra,Floyd>
昨天: 图论-概念与记录图的方法 以上是昨天的Blog,有需要者请先阅读完以上再阅读今天的Blog. 可能今天的有点乱,好好理理,认真看完相信你会懂得 分割线 第二天 引子:昨天我们简单讲了讲图的概念 ...
- 图的Prim,Kruskal,Dijkstra,Floyd算法
代码部分有点问题,具体算法没问题, 最近期末考,要过段时间才会修改 //邻接矩阵,具体情况看上一篇的图的实现template<class T>class MGraph {public: ...
- 最短路径之Floyd算法
Floyd算法又称弗洛伊德算法,也叫做Floyd's algorithm,Roy–Warshall algorithm,Roy–Floyd algorithm, WFI algorithm. Floy ...
随机推荐
- [php入门] 1、从安装开发环境环境到(庄B)做个炫酷的登陆应用
1.前言 本文适合想了解下web开发入门的小白~ 最近在根据一个网上课程学习php,课程内说道: php环境自己搭比较麻烦,可以用wamp集成开发环境,一键安装即可. 2.安装集成开发环境 下面是wa ...
- 自制Unity小游戏TankHero-2D(1)制作主角坦克
自制Unity小游戏TankHero-2D(1)制作主角坦克 我在做这样一个坦克游戏,是仿照(http://game.kid.qq.com/a/20140221/028931.htm)这个游戏制作的. ...
- JavaScript 常用功能总结
小编吐血整理加上翻译,太辛苦了~求赞! 本文主要总结了JavaScript 常用功能总结,如一些常用的JS 对象,基本数据结构,功能函数等,还有一些常用的设计模式. 目录: 众所周知,JavaScri ...
- Redis集群~StackExchange.Redis(10月6号版1.1.608.0)连接Twemproxy支持Auth指令了
回到目录 对于StackExchange.Redis这个驱动来说,之前的版本在使用Proxy为Twemproxy代理时,它是不支持Password属性的,即不支持原始的Auth指令,而我也修改过源代码 ...
- Atitit intellij idea的使用总结attilax
Atitit intellij idea的使用总结attilax 1. ideaIC-2016.2.4.exe1 1.1. Ij vs eclipse市场份额1 1.2. Ij的优点(方便的支持gro ...
- salesforce 零基础开发入门学习(十五)salesforce中formula的使用(不含Date/Time)
本文参考官方的formula介绍PDF:https://resources.docs.salesforce.com/200/latest/en-us/sfdc/pdf/salesforce_usefu ...
- 每天一个linux命令(50):crontab命令
前一天学习了 at 命令是针对仅运行一次的任务,循环运行的例行性计划任务,linux系统则是由 cron (crond) 这个系统服务来控制的.Linux 系统上面原本就有非常多的计划性工作,因此这个 ...
- localStorage使用
localStorage使用 需要注意的是,HTML5本地存储只能存字符串,任何格式存储的时候都会被自动转为字符串,所以读取的时候,需要自己进行类型的转换. 支持的情况如上图,IE在8.0的时候就支持 ...
- 关于OpenVPN的入门使用
关于OpenVPN的入门使用 1.1源代码编译安装的初步了解 1.2 安装OpenVPN 1.3 生成证书.服务器端证书.客户端证书 1.4 关于server.ovpm & client.ov ...
- Topology and Geometry in OpenCascade-Edge
Topology and Geometry in OpenCascade-Edge eryar@163.com 摘要Abstract:本文简要介绍了几何造型中的边界表示法(BRep),并结合程序说明O ...