导航:首页 > 源码编译 > 最短路径和算法

最短路径和算法

发布时间:2022-07-20 17:32:32

㈠ floyd算法求最短路径

Floyd算法适用于APSP(AllPairsShortestPaths),是一种动态规划算法,稠密图效果最佳,边权可正可负。此算法简单有效,由于三重循环结构紧凑,对于稠密图,效率要高于执行|V|次Dijkstra算法。

优点:容易理解,可以算出任意两个节点之间的最短距离,代码编写简单

缺点:时间复杂度比较高,不适合计算大量数据。

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

任意节点i到j的最短路径两种可能:

直接从i到j;
从i经过若干个节点k到j。
map(i,j)表示节点i到j最短路径的距离,对于每一个节点k,检查map(i,k)+map(k,j)小于map(i,j),如果成立,map(i,j) = map(i,k)+map(k,j);遍历每个k,每次更新的是除第k行和第k列的数。

步骤:

第1步:初始化map矩阵。
矩阵中map[i][j]的距离为顶点i到顶点j的权值;

如果i和j不相邻,则map[i][j]=∞。

如果i==j,则map[i][j]=0;
第2步:以顶点A(假设是第1个顶点)为中介点,若a[i][j] > a[i][1]+a[1][j],则设置a[i][j]=a[i][1]+a[1][j]。

㈡ 计算机网络的最短路径算法有哪些对应哪些协议

用于解决最短路径问题的算法被称做“最短路径算法”,有时被简称作“路径算法”。最常用的路径算法有:
Dijkstra算法、A*算法、SPFA算法、Bellman-Ford算法和Floyd-Warshall算法,本文主要介绍其中的三种。

最短路径问题是图论研究中的一个经典算法问题,旨在寻找图(由结点和路径组成的)中两结点之间的最短路径。
算法具体的形式包括:

确定起点的最短路径问题:即已知起始结点,求最短路径的问题。

确定终点的最短路径问题:与确定起点的问题相反,该问题是已知终结结点,求最短路径的问题。在无向图中该问题与确定起点的问题完全等同,在有向图中该问题等同于把所有路径方向反转的确定起点的问题。
确定起点终点的最短路径问题:即已知起点和终点,求两结点之间的最短路径。

全局最短路径问题:求图中所有的最短路径。
Floyd

求多源、无负权边的最短路。用矩阵记录图。时效性较差,时间复杂度O(V^3)。

Floyd-Warshall算法(Floyd-Warshall algorithm)是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题。
Floyd-Warshall算法的时间复杂度为O(N^3),空间复杂度为O(N^2)。

Floyd-Warshall的原理是动态规划:

设Di,j,k为从i到j的只以(1..k)集合中的节点为中间节点的最短路径的长度。

若最短路径经过点k,则Di,j,k = Di,k,k-1 + Dk,j,k-1;

若最短路径不经过点k,则Di,j,k = Di,j,k-1。

因此,Di,j,k = min(Di,k,k-1 + Dk,j,k-1 , Di,j,k-1)。

在实际算法中,为了节约空间,可以直接在原来空间上进行迭代,这样空间可降至二维。

Floyd-Warshall算法的描述如下:

for k ← 1 to n do

for i ← 1 to n do

for j ← 1 to n do

if (Di,k + Dk,j < Di,j) then

Di,j ← Di,k + Dk,j;

其中Di,j表示由点i到点j的代价,当Di,j为 ∞ 表示两点之间没有任何连接。

Dijkstra

求单源、无负权的最短路。时效性较好,时间复杂度为O(V*V+E),可以用优先队列进行优化,优化后时间复杂度变为0(v*lgn)。
源点可达的话,O(V*lgV+E*lgV)=>O(E*lgV)。

当是稀疏图的情况时,此时E=V*V/lgV,所以算法的时间复杂度可为O(V^2) 。可以用优先队列进行优化,优化后时间复杂度变为0(v*lgn)。
Bellman-Ford

求单源最短路,可以判断有无负权回路(若有,则不存在最短路),时效性较好,时间复杂度O(VE)。

Bellman-Ford算法是求解单源最短路径问题的一种算法。

单源点的最短路径问题是指:给定一个加权有向图G和源点s,对于图G中的任意一点v,求从s到v的最短路径。

与Dijkstra算法不同的是,在Bellman-Ford算法中,边的权值可以为负数。设想从我们可以从图中找到一个环

路(即从v出发,经过若干个点之后又回到v)且这个环路中所有边的权值之和为负。那么通过这个环路,环路中任意两点的最短路径就可以无穷小下去。如果不处理这个负环路,程序就会永远运行下去。 而Bellman-Ford算法具有分辨这种负环路的能力。
SPFA

是Bellman-Ford的队列优化,时效性相对好,时间复杂度O(kE)。(k< 与Bellman-ford算法类似,SPFA算法采用一系列的松弛操作以得到从某一个节点出发到达图中其它所有节点的最短路径。所不同的是,SPFA算法通过维护一个队列,使得一个节点的当前最短路径被更新之后没有必要立刻去更新其他的节点,从而大大减少了重复的操作次数。
SPFA算法可以用于存在负数边权的图,这与dijkstra算法是不同的。

与Dijkstra算法与Bellman-ford算法都不同,SPFA的算法时间效率是不稳定的,即它对于不同的图所需要的时间有很大的差别。
在最好情形下,每一个节点都只入队一次,则算法实际上变为广度优先遍历,其时间复杂度仅为O(E)。另一方面,存在这样的例子,使得每一个节点都被入队(V-1)次,此时算法退化为Bellman-ford算法,其时间复杂度为O(VE)。
SPFA算法在负边权图上可以完全取代Bellman-ford算法,另外在稀疏图中也表现良好。但是在非负边权图中,为了避免最坏情况的出现,通常使用效率更加稳定的Dijkstra算法,以及它的使用堆优化的版本。通常的SPFA。

㈢ 最短路径法如何计算

最短路径算法有三种,Floyd,dijkstra,Bellman_Ford。其中,Floyd适合用于计算每两点间的路径,dijkstra适合稀疏图,bellman则适合稠密图中的已知起点终点,计算最短路径的问题。时间复杂度,floyd算法为n立方,dijk为n平方,bellman为n平方,其中n是点数。dijk可用堆维护,时间复杂度可减至nlogn,而bellman可用队列维护,此方法于1994年被国人提出,命名比较土鳖叫SPFA(shortest path faster algorithm。。。)。至于如何计算,有了名字,搜一下就ok。

㈣ 最短路径优先算法

从某顶点出发,沿图的边到达另一顶点所经过的路径中,各边上权值之和最小的一条路径叫做最短路径。解决最短路的问题有以下算法,Dijkstra算法,Bellman-Ford算法,Floyd算法和SPFA算法等。

㈤ 权图中求最短路径都有哪些算法

带权图也分有向和无向两种,基本的算法可以看看书咯。
带权的无向图的最短路径又叫最小生成树,Prim算法和Kruskal算法;
带权的有向图的最短路径算法有迪杰斯特拉算法和佛洛依德算法;

㈥ 数学最短路径问题最方便的解法是什么

用于解决最短路径问题的算法被称做“最短路径算法” ,有时被简称作“路径算法” 。最常用 的路径算法有: Dijkstra 算法、 A*算法、 SPFA 算法、 Bellman-Ford 算法和 Floyd-Warshall 算法, 本文主要介绍其中的三种。 最短路径问题是图论研究中的一个经典算法问题,旨在寻找图(由结点和路径组成的)中两 结点之间的最短路径。 算法具体的形式包括: 确定起点的最短路径问题:即已知起始结点,求最短路径的问题。 确定终点的最短路径问题:与确定起点的问题相反,该问题是已知终结结点,求最短路径的 问题。 在无向图中该问题与确定起点的问题完全等同, 在有向图中该问题等同于把所有路径 方向反转的确定起点的问题。 确定起点终点的最短路径问题:即已知起点和终点,求两结点之间的最短路径。 全局最短路径问题:求图中所有的最短路径。 Floyd 求多源、无负权边的最短路。用矩阵记录图。时效性较差,时间复杂度 O(V^3)。 Floyd-Warshall 算法(Floyd-Warshall algorithm)是解决任意两点间的最短路径的一种算法, 可以正确处理有向图或负权的最短路径问题。 Floyd-Warshall 算法的时间复杂度为 O(N^3),空间复杂度为 O(N^2)。 Floyd-Warshall 的原理是动态规划: 设 Di,j,k 为从 i 到 j 的只以(1..k)集合中的节点为中间节点的最短路径的长度。 若最短路径经过点 k,则 Di,j,k = Di,k,k-1 + Dk,j,k-1; 若最短路径不经过点 k,则 Di,j,k = Di,j,k-1。 因此,Di,j,k = min(Di,k,k-1 + Dk,j,k-1 , Di,j,k-1)。 在实际算法中,为了节约空间,可以直接在原来空间上进行迭代,这样空间可降至二维。 Floyd-Warshall 算法的描述如下: 1.for k ← 1 to n do 2.for i ← 1 to n do 3.for j ← 1 to n do 4.if (Di,k + Dk,j<Di,j) then 5.Di,j ← Di,k + Dk,j; 其中 Di,j 表示由点 i 到点 j 的代价,当 Di,j 为∞表示两点之间没有任何连接。 Dijkstra 求单源、无负权的最短路。时效性较好,时间复杂度为 O(V*V+E) 。 源点可达的话,O(V*lgV+E*lgV)=>O(E*lgV) 。 当是稀疏图的情况时,此时 E=V*V/lgV,所以算法的时间复杂度可为 O(V^2) 。若是斐波那 契堆作优先队列的话,算法时间复杂度,则为 O(V*lgV + E) 。 Bellman-Ford 求单源最短路,可以判断有无负权回路(若有,则不存在最短路) ,时效性较好,时间复杂 度 O(VE) 。 Bellman-Ford 算法是求解单源最短路径问题的一种算法。 单源点的最短路径问题是指:给定一个加权有向图 G 和源点 s,对于图 G 中的任意一点 v, 求从 s 到 v 的最短路径。 与 Dijkstra 算法不同的是,在 Bellman-Ford 算法中,边的权值可以为负数。设想从我们可以 从图中找到一个环路(即从 v 出发,经过若干个点之后又回到 v)且这个环路中所有边的权 值之和为负。那么通过这个环路,环路中任意两点的最短路径就可以无穷小下去。如果不处 理这个负环路,程序就会永远运行下去。而 Bellman-Ford 算法具有分辨这种负环路的能力。 SPFA是 Bellman-Ford 的队列优化,时效性相对好,时间复杂度 O(kE)(k<<V) 。 。 与 Bellman-ford 算法类似, SPFA 算法采用一系列的松弛操作以得到从某一个节点出发到达图 中其它所有节点的最短路径。所不同的是,SPFA 算法通过维护一个队列,使得一个节点的 当前最短路径被更新之后没有必要立刻去更新其他的节点, 从而大大减少了重复的操作次数。 SPFA 算法可以用于存在负数边权的图,这与 dijkstra 算法是不同的。 与 Dijkstra 算法与 Bellman-ford 算法都不同,SPFA 的算法时间效率是不稳定的,即它对于不 同的图所需要的时间有很大的差别。 在最好情形下,每一个节点都只入队一次,则算法实际上变为广度优先遍历,其时间复杂度 仅为 O(E)。另一方面,存在这样的例子,使得每一个节点都被入队(V-1)次,此时算法退化为 Bellman-ford 算法,其时间复杂度为 O(VE)。 SPFA 算法在负边权图上可以完全取代 Bellman-ford 算法, 另外在稀疏图中也表现良好。 但是 在非负边权图中,为了避免最坏情况的出现,通常使用效率更加稳定的 Dijkstra 算法,以及 它的使用堆优化的版本。通常的 SPFA 算法在一类网格图中的表现不尽如人意。

㈦ 最短路径算法

Dijkstra算法,A*算法和D*算法

Dijkstra算法是典型最短路算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。

Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。

Dijkstra一般的表述通常有两种方式,一种用永久和临时标号方式,一种是用OPEN, CLOSE表方式,Drew为了和下面要介绍的 A* 算法和 D* 算法表述一致,这里均采用OPEN,CLOSE表的方式。

大概过程:
创建两个表,OPEN, CLOSE。
OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。
1. 访问路网中里起始点最近且没有被检查过的点,把这个点放入OPEN组中等待检查。
2. 从OPEN表中找出距起始点最近的点,找出这个点的所有子节点,把这个点放到CLOSE表中。
3. 遍历考察这个点的子节点。求出这些子节点距起始点的距离值,放子节点到OPEN表中。
4. 重复2,3,步。直到OPEN表为空,或找到目标点。

提高Dijkstra搜索速度的方法很多,常用的有数据结构采用Binary heap的方法,和用Dijkstra从起始点和终点同时搜索的方法。

A*(A-Star)算法是一种启发式算法,是静态路网中求解最短路最有效的方法。

公式表示为: f(n)=g(n)+h(n),
其中f(n) 是节点n从初始点到目标点的估价函数,
g(n) 是在状态空间中从初始节点到n节点的实际代价,
h(n)是从n到目标节点最佳路径的估计代价。

保证找到最短路径(最优解的)条件,关键在于估价函数h(n)的选取:
估价值h(n)<= n到目标节点的距离实际值,这种情况下,搜索的点数多,搜索范围大,效率低。但能得到最优解。
如果 估价值>实际值, 搜索的点数少,搜索范围小,效率高,但不能保证得到最优解。
估价值与实际值越接近,估价函数取得就越好。
例如对于几何路网来说,可以取两节点间欧几理德距离(直线距离)做为估价值,即f=g(n)+sqrt((dx-nx)*(dx-nx)+(dy-ny)*(dy-ny));这样估价函数f在g值一定的情况下,会或多或少的受估价值h的制约,节点距目标点近,h值小,f值相对就小,能保证最短路的搜索向终点的方向进行。明显优于Dijstra算法的毫无无方向的向四周搜索。
conditions of heuristic
Optimistic (must be less than or equal to the real cost)
As close to the real cost as possible
主要搜索过程:
创建两个表,OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。
遍历当前节点的各个节点,将n节点放入CLOSE中,取n节点的子节点X,->算X的估价值->
While(OPEN!=NULL)
{
从OPEN表中取估价值f最小的节点n;
if(n节点==目标节点) break;
else
{
if(X in OPEN) 比较两个X的估价值f //注意是同一个节点的两个不同路径的估价值
if( X的估价值小于OPEN表的估价值 )
更新OPEN表中的估价值; //取最小路径的估价值
if(X in CLOSE) 比较两个X的估价值 //注意是同一个节点的两个不同路径的估价值
if( X的估价值小于CLOSE表的估价值 )
更新CLOSE表中的估价值; 把X节点放入OPEN //取最小路径的估价值
if(X not in both)
求X的估价值;
并将X插入OPEN表中; //还没有排序
}
将n节点插入CLOSE表中;
按照估价值将OPEN表中的节点排序; //实际上是比较OPEN表内节点f的大小,从最小路径的节点向下进行。
}

A*算法和Dijistra算法的区别在于有无估价值,Dijistra算法相当于A*算法中估价值为0的情况。

动态路网,最短路算法 D*A* 在静态路网中非常有效(very efficient for static worlds),但不适于在动态路网,环境如权重等不断变化的动态环境下。

D*是动态A*(D-Star,Dynamic A*) 卡内及梅隆机器人中心的Stentz在1994和1995年两篇文章提出,主要用于机器人探路。是火星探测器采用的寻路算法。

主要方法:
1.先用Dijstra算法从目标节点G向起始节点搜索。储存路网中目标点到各个节点的最短路和该位置到目标点的实际值h,k(k为所有变化h之中最小的值,当前为k=h。每个节点包含上一节点到目标点的最短路信息1(2),2(5),5(4),4(7)。则1到4的最短路为1-2-5-4。
原OPEN和CLOSE中节点信息保存。
2.机器人沿最短路开始移动,在移动的下一节点没有变化时,无需计算,利用上一步Dijstra计算出的最短路信息从出发点向后追述即可,当在Y点探测到下一节点X状态发生改变,如堵塞。机器人首先调整自己在当前位置Y到目标点G的实际值h(Y),h(Y)=X到Y的新权值c(X,Y)+X的原实际值h(X).X为下一节点(到目标点方向Y->X->G),Y是当前点。k值取h值变化前后的最小。
3.用A*或其它算法计算,这里假设用A*算法,遍历Y的子节点,点放入CLOSE,调整Y的子节点a的h值,h(a)=h(Y)+Y到子节点a的权重C(Y,a),比较a点是否存在于OPEN和CLOSE中,方法如下:
while()
{
从OPEN表中取k值最小的节点Y;
遍历Y的子节点a,计算a的h值 h(a)=h(Y)+Y到子节点a的权重C(Y,a)
{
if(a in OPEN) 比较两个a的h值
if( a的h值小于OPEN表a的h值 )
{ 更新OPEN表中a的h值;k值取最小的h值
有未受影响的最短路经存在
break;
}
if(a in CLOSE) 比较两个a的h值 //注意是同一个节点的两个不同路径的估价值
if( a的h值小于CLOSE表的h值 )
{
更新CLOSE表中a的h值; k值取最小的h值;将a节点放入OPEN表
有未受影响的最短路经存在
break;
}
if(a not in both)
将a插入OPEN表中; //还没有排序
}
放Y到CLOSE表;
OPEN表比较k值大小进行排序;
}
机器人利用第一步Dijstra计算出的最短路信息从a点到目标点的最短路经进行。

D*算法在动态环境中寻路非常有效,向目标点移动中,只检查最短路径上下一节点或临近节点的变化情况,如机器人寻路等情况。对于距离远的最短路径上发生的变化,则感觉不太适用。

㈧ 最短路径的Dijkstra算法

Dijkstra算法(迪杰斯特拉)是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。可以用堆优化。
Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。
Dijkstra一般的表述通常有两种方式,一种用永久和临时标号方式,一种是用OPEN, CLOSE表方式,Drew为了和下面要介绍的 A* 算法和 D* 算法表述一致,这里均采用OPEN,CLOSE表的方式。
其采用的是贪心法的算法策略
大概过程:
创建两个表,OPEN, CLOSE。
OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。
1. 访问路网中距离起始点最近且没有被检查过的点,把这个点放入OPEN组中等待检查。
2. 从OPEN表中找出距起始点最近的点,找出这个点的所有子节点,把这个点放到CLOSE表中。
3. 遍历考察这个点的子节点。求出这些子节点距起始点的距离值,放子节点到OPEN表中。
4. 重复第2和第3步,直到OPEN表为空,或找到目标点。 #include<iostream>#include<vector>usingnamespacestd;voiddijkstra(constint&beg,//出发点constvector<vector<int>>&adjmap,//邻接矩阵,通过传引用避免拷贝vector<int>&dist,//出发点到各点的最短路径长度vector<int>&path)//路径上到达该点的前一个点//负边被认作不联通//福利:这个函数没有用任何全局量,可以直接复制!{constint&NODE=adjmap.size();//用邻接矩阵的大小传递顶点个数,减少参数传递dist.assign(NODE,-1);//初始化距离为未知path.assign(NODE,-1);//初始化路径为未知vector<bool>flag(NODE,0);//标志数组,判断是否处理过dist[beg]=0;//出发点到自身路径长度为0while(1){intv=-1;//初始化为未知for(inti=0;i!=NODE;++i)if(!flag[i]&&dist[i]>=0)//寻找未被处理过且if(v<0||dist[i]<dist[v])//距离最小的点v=i;if(v<0)return;//所有联通的点都被处理过flag[v]=1;//标记for(inti=0;i!=NODE;++i)if(adjmap[v][i]>=0)//有联通路径且if(dist[i]<0||dist[v]+adjmap[v][i]<dist[i])//不满足三角不等式{dist[i]=dist[v]+adjmap[v][i];//更新path[i]=v;//记录路径}}}intmain(){intn_num,e_num,beg;//含义见下cout<<输入点数、边数、出发点:;cin>>n_num>>e_num>>beg;vector<vector<int>>adjmap(n_num,vector<int>(n_num,-1));//默认初始化邻接矩阵for(inti=0,p,q;i!=e_num;++i){cout<<输入第<<i+1<<条边的起点、终点、长度(负值代表不联通):;cin>>p>>q;cin>>adjmap[p][q];}vector<int>dist,path;//用于接收最短路径长度及路径各点dijkstra(beg,adjmap,dist,path);for(inti=0;i!=n_num;++i){cout<<beg<<到<<i<<的最短距离为<<dist[i]<<,反向打印路径:;for(intw=i;path[w]>=0;w=path[w])cout<<w<<<-;cout<<beg<<' ';}}

㈨ 最短路径的解决方法

用于解决最短路径问题的算法被称做“最短路径算法”, 有时被简称作“路径算法”。 最常用的路径算法有:
Dijkstra算法
SPFA算法Bellman-Ford算法
Floyd算法Floyd-Warshall算法
Johnson算法
A*算法
所谓单源最短路径问题是指:已知图G=(V,E),我们希望找出从某给定的源结点S∈V到V中的每个结点的最短路径。
首先,我们可以发现有这样一个事实:如果P是G中从vs到vj的最短路,vi是P中的一个点,那么,从vs沿P到vi的路是从vs到vi的最短路。

㈩ 求解:图论中常见的最短路径算法有几种都是什么

主要是有三种、、
第一种是最直接的贪心dijkstra算法、、可以利用堆数据结构进行优化、、缺点就是不能求有负权的最短路与判断负环、、
第二种是bellman-ford算法、、根据松弛操作的性质是可以来判断负环的、、时间复杂度是O(nm)的、、
第三种是SPFA算法、、把他单独拿出来作为一种算法并不是非常好的、、他的实质应该是上面的bellman-ford算法的队列优化时间复杂度更低、O(KE)、K的值约等于2、、

阅读全文

与最短路径和算法相关的资料

热点内容
javavector的用法 浏览:972
osi实现加密的三层 浏览:223
大众宝来原厂中控如何安装app 浏览:906
linux内核根文件系统 浏览:233
3d的命令面板不见了 浏览:518
武汉理工大学服务器ip地址 浏览:139
亚马逊云服务器登录 浏览:515
安卓手机如何进行文件处理 浏览:62
mysql执行系统命令 浏览:921
php支持curlhttps 浏览:134
新预算法责任 浏览:435
服务器如何处理5万人同时在线 浏览:242
哈夫曼编码数据压缩 浏览:415
锁定服务器是什么意思 浏览:376
场景检测算法 浏览:608
解压手机软件触屏 浏览:339
方舟pv怎么转服务器 浏览:100
数据挖掘中误差值算法函数 浏览:119
php开发套件 浏览:191
服务器的spi板是什么 浏览:897