当前位置:首页 » 操作系统 » cdijkstra算法

cdijkstra算法

发布时间: 2022-07-03 15:49:18

⑴ 怎样用matlab编程实现Dijkstra算法

Dijkstra算法是寻找最短路径的一种搜索算法,由荷兰科学家提出。
算法描述:通过为每个节点保留目前为止所找到的从s到e的最短路径。为了记录最佳路径轨迹,记录路径上每个节点的前趋,通过回溯法找出最短路径轨迹。

在网上搜索一些版本的Matlab实现方法,感觉都有些毛病。经过修改,得到比较好的效果。

[cpp] view plain
function [ distance path] = Dijk( W,st,e )
%DIJK Summary of this function goes here
% W 权值矩阵 st 搜索的起点 e 搜索的终点
n=length(W);%节点数
D = W(st,:);
visit= ones(1:n); visit(st)=0;
parent = zeros(1,n);%记录每个节点的上一个节点

path =[];

for i=1:n-1
temp = [];
%从起点出发,找最短距离的下一个点,每次不会重复原来的轨迹,设置visit判断节点是否访问
for j=1:n
if visit(j)
temp =[temp D(j)];
else
temp =[temp inf];
end

end

[value,index] = min(temp);

visit(index) = 0;

%更新 如果经过index节点,从起点到每个节点的路径长度更小,则更新,记录前趋节点,方便后面回溯循迹
for k=1:n
if D(k)>D(index)+W(index,k)
D(k) = D(index)+W(index,k);
parent(k) = index;
end
end

end

distance = D(e);%最短距离
%回溯法 从尾部往前寻找搜索路径
t = e;
while t~=st && t>0
path =[t,path];
p=parent(t);t=p;
end
path =[st,path];%最短路径

end

测试:
测试用例1

[cpp] view plain
W=[0 50 inf 40 25 10
50 0 15 20 inf 25
inf 15 0 10 20 inf
40 20 10 0 10 25
25 inf 20 10 0 55
10 25 inf 25 55 0];
[cpp] view plain

[cpp] view plain
[distance,path]=Dijk(W,1,4);
>> distance

distance =

35

>> path

path =

1 6 4

从节点1到节点4最短距离路径为1-->6-->4, 最短距离为35

⑵ dijkstra算法

楼上正解,你找个图自己用此算法实践一下就知道了,从A点出发,发现离A最近的点是B点,那么我们就已经认为A到B的最短距离就是AB了,如果有负数,就指不定冒出个C点,AC+CB<AB;或者冒出个DE为很大的负值,AC+CD+DE+EF+FB<AB;等等诸如此类的情况。
简单说来,你驾车从家出发到某地沿某条路只需经过一个收费站,但是远在外省某地有个站不但不收你的费,你去了还会给你个千八百万的欢迎光临费,你能说你直接沿着这条路去某地是最省费用的?不计时间成本,绕到外省那个给你钱的地方,再绕回到你的目的地,还能赚钱呢。
而且一般权值为负的图研究也比较少。有些带负权的图,某些点间还没有最小距离呢。中间出个带某条负权很大的边的环圈,绕此一圈所经过的距离反而减少了,那就一直在此圈上绕啊绕啊绕到负的足够大溢出为止。
当然考虑各种自己随便假设出来的变种问题也是很有趣的。比如说边带有多个权值对应多次经过改变的消费,上面的问题有可能变成有解的。话说那个站会后悔,第二次经过它会收回100万,第三次经过收回250万,这样的话你只需要经过一次就够了,问题也是有解的。再比如说对于多权重图,从A点出发经过B点到达C点的最短路线,就不是简单的AB最短路线+BC最短路线了,说不定两者有重合边,第二次经过来个天价就傻眼了。其实这种图貌似应该可以转化成单权重图的,我直觉估计啊,刚随便想出这个问题,还没去思考这个问题的解^_^

⑶ dijkstra算法是什么

Dijkstra算法是由荷兰计算机科学家狄克斯特拉(Dijkstra)于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。

其基本原理是:每次新扩展一个距离最短的点,更新与其相邻的点的距离。当所有边权都为正时,由于不会存在一个距离更短的没扩展过的点,所以这个点的距离永远不会再被改变,因而保证了算法的正确性。

不过根据这个原理,用Dijkstra求最短路的图不能有负权边,因为扩展到负权边的时候会产生更短的距离,有可能就破坏了已经更新的点距离不会改变的性质。

举例来说,如果图中的顶点表示城市,而边上的权重表示着城市间开车行经的距离。Dijkstra算法可以用来找到两个城市之间的最短路径。

Dijkstra算法的输入包含了一个有权重的有向图G,以及G中的一个来源顶点S。我们以V表示G中所有顶点的集合。每一个图中的边,都是两个顶点所形成的有序元素对。(u,v)表示从顶点u到v有路径相连。我们以E所有边的集合,而边的权重则由权重函数w: E→[0,∞]定义。

因此,w(u,v)就是从顶点u到顶点v的非负花费值(cost)。边的花费可以想象成两个顶点之间的距离。任两点间路径的花费值,就是该路径上所有边的花费值总和。

已知有V中有顶点s及t,Dijkstra算法可以找到s到t的最低花费路径(i.e.最短路径)。这个算法也可以在一个图中,找到从一个顶点s到任何其他顶点的最短路径。

⑷ Dijkstra 算法是什么

迪杰斯特拉算法用来解决从顶点v0出发到其余顶点的最短路径,该算法按照最短路径长度递增的顺序产生所以最短路径。
对于图G=(V,E),将图中的顶点分成两组:
第一组S:已求出的最短路径的终点集合(开始为{v0})。
第二组V-S:尚未求出最短路径的终点集合(开始为V-{v0}的全部结点)。
算法将按最短路径长度的递增顺序逐个将第二组的顶点加入到第一组中,直到所有顶点都被加入到第一组顶点集S为止。
【算法思想】
g为用邻接矩阵表示的带权图。
(1)S<-{v0};
dist[i]=g.arcs[v0][v1].adj;(vi属于V-S)(将v0到其余顶点的最短路径长度初始化为权值)
(2)选择vk,使得:dist[k]=min(dist[i]|vi属于V-S)vk为目前求得的下一条从v0出发的最短路径的终点。
(3)将vk加入S;
(4)修正从v0出发到集合V-S上任一顶点vi的最短路径长度:从v0出发到集合V-S上任一顶点vi的当前最短路径的长度为dist[i],从v0出发,中间经过新加入S的vk,然后到达集合V-S上任一顶点vi的路径长度为:dist[k]+g.arcs[k][i].adj
如果:dist[k]+g.arcs[k][i].adj<dist[i]
则dist[i]=dist[k]+g.arcs[k][i].adj
(5)重复(2)~(4)n-1次,即可按最短路径长度的递增顺序,逐个求出v0到图中其余每个顶点的最短路径。
【算法描述】
typedef unsigned int WeightType;
typedef WeightType AdjType;
typedef SeqList VertexSet;

ShortestPath_DJS(AdjMatrix g,int v0,WeightType dist[MAX_VERTEX_NUM],VertexSet path[MAX_VERTEX_NUM])
/* path[i]中存放顶点i的当前最短路径。dist[i]中存放顶点i的当前最短路径长度*/
{
VertexSet s; /* s为已找到最短路径的终点集合 */
for(i=0;i<g.vexnum;i++) /* 初始化dist[i]和path [i] */
{
InitList(&path[i]);
dist[i]=g.arcs[v0][i].adj;
if(dist[i]<INFINITY)
{
AddTail(&path[i],g.vexs[v0]); /* AddTail为表尾添加操作*/
AddTail(&path[i],g.vexs[i]);
}
}
InitList(&s);
AddTail(&s,g.vexs[v0]); /* 将v0看成第一个已找到最短路径的终点*/
/*以上部分完成了对向量最短路径长度dist[ ],路径path[],顶点集s[]的初始化工作*/

/*以下部分通过n-1次循环,将第二组顶点集V-S中的顶点按照递增有序方式加入到S集合中,并求得从顶点v0出发到达图中其余顶点的最短路径。*/
for(t=1;t<=g.vexnum-1;t++) /*求v0到其余n-1个顶点的最短路径(n= g.vexnum )*/
{
min=INFINITY;
for(i=0;i<g.vexnum;i++)
if(!Member(g.vex[i],s)&&dist[i]<min)
{
k =i;
min=dist[i];
}
AddTail(&s,g.vexs[k]);
for(i=0;i<g.vexnum;i++) /*修正dist[i], i∈V-S*/
if(!Member(g.vex[i],s)&&g.arcs[k][i].adj!=INFINITY&&(dist[k]+g.arcs[k][i].adj<dist[i]))
{
dist[i]=dist[k]+g.arcs[k][i].adj;
path[i]=path[k];
AddTail(&path[i],g.vexs[i]); /* path[i]=path[k]∪{Vi} */
}
}
}
另外说一下,该算法的时间复杂度很明显,为O(n^2)。

⑸ Prim和Dijkstra算法的区别

在图论中,Prim算法是计算最小生成树的算法,而Dijkstra算法是计算最短路径的算法。二者看起来比较类似,因为假设全部顶点的集合是V,已经被挑选出来的点的集合是U,那么二者都是从集合V-U中不断的挑选权值最低的点加入U。
二者的不同之处在于“权值最低”的定义不同,Prim的“权值最低”是相对于U中的任意一点而言的,也就是把U中的点看成一个整体,每次寻找V-U中跟U的距离最小(也就是跟U中任意一点的距离最小)的一点加入U;而Dijkstra的“权值最低”是相对于v0而言的,也就是每次寻找V-U中跟v0的距离最小的一点加入U。

一个可以说明二者不等价的例子是有四个顶点(v0, v1, v2, v3)和四条边且边值定义为(v0, v1)=20, (v0, v2)=10, (v1, v3)=2, (v3, v2)=15的图,用Prim算法得到的最小生成树中v0跟v1是不直接相连的,也就是在最小生成树中v0v1的距离是v0->v2->v3->v1的距离是27,而用Dijkstra算法得到的v0v1的距离是20,也就是二者直接连线的长度。

⑹ Dijkstra算法

这是我自己写的一个简单的DIJKSTRA算法,其中测试数据是
6 8
0 2 10
0 4 30
0 5 100
1 2 5
2 3 50
3 5 10
4 3 20
4 5 60
结构清晰简单,对于你要搞懂这个算法很有帮助。有不懂的可以问我:我的QQ是396730783
#include"stdio.h"
#define MAX 100000000
int main()
{
int map[101][101];
int dis[101];
int a,b,c;
int i,j,k,n,m;
int min;
while(scanf("%d",&n)==1)
{
int final[101] = {0};
scanf("%d",&m);
for(i=0;i<n;i++)
for(j=i;j<n;j++)
{
map[i][j] = map[j][i] = MAX;
}
for(i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
map[a][b] = c;
}
for(i=1;i<n;i++)
{
dis[i] = map[0][i];
}
dis[0] = 0;
final[0] = 1;
for(i=0;i<n-1;i++)
{
min = MAX;
for(j=1;j<n;j++)
{
if(!final[j] && min > dis[j])
{
min = dis[j];
k = j;
}
}
final[k]=1;
for(j=1;j<n;j++)
{
if(!final[j] && dis[k]+map[k][j]<dis[j])
dis[j] = dis[k]+map[k][j];
}
}
for(i=1;i<n;i++)
{
if(dis[i] == MAX)
printf("不可通");
else
printf("%5d",dis[i]);
}
printf("\n");

}
return 0;

}

⑺ 解释一下dijkstra算法这个计算过程的意思 怎么算的

最近也看到这个算法,不过主要是通过C语言介绍的,不太一样,但基本思想差不多。下面只是我个人的看法不一定准确。
Dijkstra算法主要解决指定某点(源点)到其他顶点的最短路径问题。
基本思想:每次找到离源点最近的顶点,然后以该顶点为中心(过渡顶点),最终找到源点到其余顶点的最短路。

t=1:令源点(v_0)的标号为永久标号(0,λ)(右上角加点), 其他为临时(+无穷,λ). 就是说v_0到v_0的距离是0,其他顶点到v_0的距离为+无穷。t=1时,例5.3上面的步骤(2)(3)并不能体现

t=2:第1步v_0(k=0)获得永久标号,记L_j为顶点标号当前的最短距离(比如v_0标号(0,λ)中L_0=0), 边(v_k,v_j)的权w_kj. 步骤(2)最关键,若v_0与v_j之间存在边,则比较L_k+w_kj与L_j, 而L_k+w_kj=L_0+w_0j<L_j=+无穷。
这里只有v_1,v_2与v_0存在边,所以当j=1,2时修改标号, 标号分别为(L_1, v_0)=(1, v_0), (L_2, v_0)=(4, v_0), 其他不变。步骤(3)比较所有临时标号中L_j最小的顶点, 这里L_1=1最小,v_1获得永久标号(右上角加点)。

t=3: 第2步中v_1获得永久标号(k=1), 同第2步一样,通过例5.3上面的步骤(2)(3),得到永久标号。 步骤(2),若v_1与v_j(j=2,3,4,5(除去获得永久标号的顶点))之间存在边,则比较L_1+w_1j与L_j。这里v_1与v_2,v_3,v_,4存在边,
对于v_2, L_1+w_12=1+2=3<L_2=4, 把v_2标号修改为(L_1+w_12, v_1)=(3, v_1);
对于v_3, L_1+w_13=1+7=8<L_3=+无穷, 把v_3标号修改为(L_1+w_13, v_1)=(8, v_1);
对于v_4, L_1+w_14=1+5=6<L_4=+无穷, 把v_4标号修改为(L_1+w_14, v_1)=(6, v_1);
v_5与v_1不存在边,标号不变。步骤(3), 找这些标号L_j最小的顶点,这里v_2标号最小

t=4: k=2, 与v_2存在边的未获得永久标号的顶点只有v_4, 比较L_2+w_24=3+1=4<L_4=6, 把v_4标号修改为(L_2+w_24, v_2)=(4, v_2); 其他不变。步骤(3), L_4=4最小。

t=5: k=4, 同理先找v_4邻接顶点,比较,修改标号,找L_j最小
t=6: 同理

啰嗦的这么多,其实步骤(2)是关键,就是通过比较更新最短路径,右上角标点的就是距离源点最近的顶点,之后每一步就添加一个新的”源点”,再找其他顶点与它的最短距离。

迪杰斯特拉算法(Dijkstra)(网络):
http://ke..com/link?url=gc_mamV4z7tpxwqju6BoqxVOZ_josbPNcGKtLYJ5GJsJT6U28koc_#4
里面有个动图,更形象地说明了该算法的过程。(其中每次标注的一个红色顶点out就和你的这本书中获得永久标号是相似的)

⑻ 最短路径的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<<' ';}}

热点内容
如何改微信支付密码 发布:2024-11-17 21:41:33 浏览:703
云狗通过什么连接服务器 发布:2024-11-17 21:11:34 浏览:15
qq邮箱访问权限的限制 发布:2024-11-17 21:07:16 浏览:422
查IP能查到在哪里买的服务器吗 发布:2024-11-17 20:56:42 浏览:684
rust为什么连接不了服务器 发布:2024-11-17 20:56:37 浏览:554
修改字段值的sql语句 发布:2024-11-17 20:56:36 浏览:569
无法启用ftp服务 发布:2024-11-17 20:33:54 浏览:838
安卓平板的管理工具在哪里 发布:2024-11-17 20:21:48 浏览:522
淘宝整机怎么配置 发布:2024-11-17 20:21:05 浏览:291
linux如何安装源码包 发布:2024-11-17 20:15:40 浏览:198