您的位置:首页 > 其它

最短路径之迪杰斯特拉(Dijkstra)算法

2018-07-22 17:42 197 查看

迪杰斯特拉(Dijkstra)算法:这个算法我感觉和bfs算法有一定的相像之处,就是通过大量的遍历,得到最后的结果。我在网上卡了许多类似的文章,也是云里雾里,大概意思都说出来了,大师有一点小细节没有说明白,在这里我就自己的体会给大家分享一下。

 

1.指定网或者图中的一点作为根,这里将所有的定点分为两类,一类时已经找到到目标点距离最近的点,一类是还没有找到离目标点最近的点(也可以说是不确定是不是到目标点最近的点)。

2.从目标点出发,遍历与它相邻的节点,并选定最近的节点(这个时候,这个距离就是目标点到该点的最近距离,因为你想,已知的其他路到目标点的距离都比它远,所以不可能出现从其他点折回该点的情况),这时候再以刚才找到的那个点为“心”,找和它相邻的点的最小距离(当然,不能往回走),就这样一个点一个点的找,到最后就全都找到了。

3.要强调的是下面代码的更新value数组,因为value数组保存的是从目标点到各点的最近距离,所以,不需要考虑其他路线,只需要将value中的值与对应找到的线路的距离进行比较即可(每循环一次都会更新value数组,所以value数组始终保存的是当前情况下各点到目标点最近的路程)。

看题&代码

要求从下图中找到从v0出发到所有点的最近距离。

 


 

 

[code]#include<stdio.h>
#define M 65535

int before[9];
int value[9];
int sign[9];

int map[9][9]={
0,1,5,M,M,M,M,M,M,
1,0,3,7,5,M,M,M,M,
5,3,0,M,1,7,M,M,M,
M,7,M,0,2,M,3,M,M,
M,5,1,2,0,3,6,9,M,
M,M,7,M,3,0,M,5,M,
M,M,M,3,6,M,0,2,7,
M,M,M,M,9,5,2,0,4,
M,M,M,M,M,M,7,4,0
};

main()
{

for(int i=0;i<9;i++)//初始化value数组(假设v0为起始点)
{
value[i]=map[0][i];
before[i]=0;
}

sign[0]=1;//自己到自己的距离为零,无需查找

for(int i=1;i<9;i++)//没进行一次就找到v0到某个顶点的最小值
{
int min=M;
int k=0;

for(int j=1;j<9;j++)//这个for循环筛选出value数组中到vo最小的值,也就是该点到 v0的最小值了已经
{
if(sign[j]!=1&&value[j]<min)
{
min=value[j];
k=j;
}
}

sign[k]=1;//设置筛选出来的点的标记为1,表示该点到v0的最小值已经找,无需再对该点进行处理

for(int w=1;w<9;w++)//更新value数组,没找到一个点,都可能产生到某点的新路径,一旦新路径
//出现,就比较value中存储的老路径与新路径那个近,并更新到value中,所以
//value中始终出现的是到所有点的最近距离。 只是再后续的更新中可能被替代
{
if(sign[w]!=1&&(min+map[k][w])<value[w])//判断该点的到v0的最近路径是否找到,一旦找到
//就不再继续更新了
{
value[w]=map[k][w]+min;
before[w]=k;//将更新后的value数组对应的前驱节点存入before数组中方便以后查看
}
}
}

for(int i=0;i<9;i++)
{
printf("%d\n",value[i]);
}

printf("*********************\n");

for(int i=0;i<9;i++)
{
printf("%d\n",before[i]);
}

printf("*********************\n");

for(int i=0;i<9;i++)
{
printf("%d\n",sign[i]);
}

return 0;

}

完成了!

 

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: