新发现或大错误!!高手看看,starfish别漏了。

jerry_baimor 2001-07-15 03:15:28
因为好多聪明多的人都推荐Dij,floyd算法,而我又不聪明,所以我的一定有错。

已知:用十字链表存储的有向网络,弧的权值存在ArcBox里。
求解:从给定原点(eg. v0)到其余顶点的最短路径。
解:用Broadth_first_search,
by way of
队列queue
辅助数组
int _priorVex[MAX_VERTEX_NUM+1]; 纪录当前最短路径本节点的立即前驱节点的下标
int _shortPath[MAX_VERTEX_NUM+1]; 记录本节点的当前最短路径的权值

算法:假设所定原点是v0
enqueue(v0);
while(queue not empty){
p=dequeue();
for(q=p.firstout;q;q=p.nextout(q)){
if(_shortPath(p)+weight(p,q) < _shortPath(q)){
_shortPath(q) := _shortPath(p)+weight(p,q);
_priorVex(q)=p;
if(q is not in queue){
enqueue(q);
}
}
}
}


我的考虑是:
假设v0...v1...v2是v0到v2的最短路径,那么可以断言
此中的v0...v1是v0到v1的最短路径(反证法)
而此路径中的任意一点都对应一条弧,弧又对应于<tail,head>。
对应于顶点v,若它的_shortPath改变了(定由于某条进入它的弧引起的变化),那么以v为弧尾的弧的弧头都应看看有没有变化,所以
if(q is not in queue){
enqueue(q);
}


我还有源代码,谁有兴趣请留下mail,谢谢。
...全文
124 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
kz 2001-07-17
  • 打赏
  • 举报
回复
原来这一论坛是qingrun(青润)最高,不过好长一段时间没来以后,现在变成starfish(海星)和duz(肚子)最高了
starfish 2001-07-17
  • 打赏
  • 举报
回复
优先队列中的每一个元素都有一个优先级,元素x的优先级是p(x),它是一个定义在全序集上的函数(一般可取一个实数或整数)。优先队列和一般的队列最大的不同在于优先队列每次出队的元素是优先级最高的元素。实现优先队列的方法有很多,目前最快的是用Fibonacci堆。

是我看错了,如果图中无负权回路的话,这个算法是正确的。但是这个算法的效率非常低!

如果源点v0的相邻节点依次为v1,v2,v3,..vk,其中
w(v0,vk)+w(vk,v1)< w(v0,vk-1)+w(vk-1,v1)<...< w(v0,v2)+w(v2,v1)< w(v0,v1),
因为v1是v0的第一个相邻节点,所以v1至少要入队k次!而图中以v1为根的树中的所有节点也要重复的搜索!这个复杂度比较难分析,但是直觉上应该是指数级的!如果你有兴趣的话可以自己随机生成一个具有1000个节点的图测试一下你的这个算法的效率(要多做几次)。理论上给出其复杂性的公式比较困难。

但是如果使用优先队列的话,每次在队列中取一个_shortPath(p)具有最小值的节点出来,这样已经入过队列的节点就可以不必再进入队列(可以用一个标志来记录某个节点是否进入过队列),复杂度会大大地下降,最坏也可以达到O(VE)的数量级。
jerry_baimor 2001-07-17
  • 打赏
  • 举报
回复
忘了提了,数组_shortPath要初始化,
//intialize part of arrays,whose indices correspond to those in the static list//
for(i=listhead;i;i=list[i].next){
_shortPath[i]=MAXNUM;
}//除了所定原点以外,其余的顶点都初始化为MAXNUM
v=locateVex(e);
_shortPath[v]=0;//原点初始化为0

请starfish不小赐教,再次感激涕零。
jerry_baimor 2001-07-17
  • 打赏
  • 举报
回复
starfish,我再问一下。
Q1: 优先队列和普通队列有设么区别?优先队列不就是可以insert,delete,min操作吗?书是使用2-3数来实现的。
还有
Q2: 你的图是不是v1->v2(weight: 1),v2->v3(weight: 2),v1->v3(weight: 10),我的算法可以完成,结果是:

------- RESULT -----
from 1 to 3
...weight : 3
...route : 3 <-- 2 <-- 1
from 1 to 2
...weight : 1
...route : 2 <-- 1


Q3: 老实说,优先队列等除了操作以外,有没有思想在里面?Starfish等高手指教。
btw,starfish你好厉害!!!我自从sina查到你的网站,我就被吓蒙了。希望继续努力。
superwolf 2001-07-16
  • 打赏
  • 举报
回复
kao,我在这里很久了,简直佩服死海星了!

海星,能不能介绍一下你自己,让我们知道差距出在哪里?
along_zju 2001-07-16
  • 打赏
  • 举报
回复
和dijkstra算法实现有点不一样,但是思想是一样的
其实我还觉得这样好写程序,

ps.不需要用队列,用涂色的办法就可以了
starfish 2001-07-16
  • 打赏
  • 举报
回复
TO:jerry_baimor(DNA出错)
刚才仔细看了一下你的算法,你这里的队列必须是优先队列才行,如果是一般的队列的话,这个算法是错的!队列中的节点必须按照当前该节点到V0的最短距离由小到大排列。
例如一个简单情形:
1---2
|../
|./
3
w(1,2)=1,w(1,3)=10,w(2,3)=2
从1到3的最短路径是1-2-3,距离1+2=3;
但是如果你的算法中的队列不是优先队列的话,则如果图的结构是
1->3->2
|
2->1->3
|
3->1->2
按照你的算法就会出错!
林仪明 2001-07-16
  • 打赏
  • 举报
回复
莫名其妙!
jerry_baimor 2001-07-16
  • 打赏
  • 举报
回复
对不起,我只是自己想了,原来还是dij算法。那么,我又问,对算法的复杂度如何算那?
starfish执教
starfish 2001-07-16
  • 打赏
  • 举报
回复
有什么问题么?这不就是dijkstra算法么?
ftco 2001-07-16
  • 打赏
  • 举报
回复
高手!
up :)
starfish 2001-07-16
  • 打赏
  • 举报
回复
Dijkstra算法有n中实现方法呢,只不过是其中用的数据结构不同罢了。最好的实现方法是用Fibonacci堆,可以将复杂度提高到O(VlgV+E)!Dijkstra算法只是一种基本的算法框架(或者说算法思想),实现这个框架的不同方法都属于Dijkstra算法!
jerry_baimor 2001-07-15
  • 打赏
  • 举报
回复
这么没人回答。都是天才还是笨蛋???
拜托看看。请starfish海星来指点一下!!!

33,006

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧