- 在线时间
- 0 小时
- 最后登录
- 2010-9-11
- 注册时间
- 2010-4-19
- 听众数
- 3
- 收听数
- 0
- 能力
- 0 分
- 体力
- 128 点
- 威望
- 0 点
- 阅读权限
- 20
- 积分
- 42
- 相册
- 0
- 日志
- 1
- 记录
- 2
- 帖子
- 6
- 主题
- 1
- 精华
- 0
- 分享
- 0
- 好友
- 8
升级   38.95% 该用户从未签到
- 自我介绍
- 我是一个数模的喜爱者
 群组: matlab共享与进阶 群组: MATLAB讨论交流群 群组: MATLAB 群组: Matlab讨论组 |
%最短路问题(迪克斯特拉算法) |, v/ v+ _4 e. [. a
clear;
, `/ l8 \+ ]4 |+ Y- b6 Eclc;; V: p% r. r4 \+ @- h, n/ b
M=10000;5 ?5 R: O; g4 v* Z$ a9 T
a(1,:)=[0,50,M,40,25,10];
$ ? l( R5 f, a! |2 N9 C. } ma(2,:)=[zeros(1,2),15,20,M,25];0 h( A: Z8 n, M9 y
a(3,:)=[zeros(1,3),10,20,M];
0 w8 }+ d1 a' K3 J( E) O1 v+ N" qa(4,:)=[zeros(1,4),10,25];0 M! K: H' v& ^% c. x4 k4 h# f" l
a(5,:)=[zeros(1,5),55];
# W1 L: K5 E8 x+ y1 V7 [a(6,:)=zeros(1,6);
( h2 c) Z( P9 K* F& qa=a+a';
# Z0 V( B, J5 t$ ~$ V%length函数返回的是矩阵中行数和列数中较大的长度
+ H0 X/ x0 a) Xpb(1:length(a))=0;%生成一个一行多列的0矩阵. K1 Q9 k* j$ w. R9 }) h7 _& p
pb(1)=1; %第一个数赋值为19 W" \! X7 f' O6 u6 a
index1=1;' z4 A, Y7 [$ P+ d
index2=ones(1,length(a));%生成一个一行多列的1矩阵
/ V9 ]8 G; F* cd(1:length(a))=M; d(1)=0; temp=1;4 Z7 r" L } A% s' @) H+ S
%sum函数为各行之和
* V1 E$ m: |3 M' F, s" d0 I- kwhile sum(pb)<length(a)
! X6 U$ _% f8 Y% p8 v; p, `! N tb=find(pb==0);%find函数返回的是pb矩阵中数值为0的坐标(2,3,4,5,6....)0 J; R0 y, ~. f$ h9 v, y! f. `: L
d(tb)=min(d(tb),d(temp)+a(temp,tb)); \) ~& N" [2 _5 S
tmpb=find(d(tb)==min(d(tb)));
- w. X) a3 Q" P: U temp=tb(tmpb(1));
$ M1 R2 V8 H. {7 t5 C pb(temp)=1;$ c# Y" w( B4 H: x
index1=[index1,temp];+ ~# G( U. d+ u
index=index1(find(d(index1)==d(temp)-a(temp,index1))); q: j8 y* l8 d# d; I) t- R! t4 `
if length(index)>=2
! c/ D1 Y. n3 w. k index=index(1);/ P+ L/ S( @ U
end
3 `, |+ M" L3 M/ k$ J index2(temp)=index;- d' `8 h6 f" |% ?* P
end
& d8 k/ v; V s2 ~0 v) k0 ?* [3 fd,index1,index2( Y% @, E% S! p [; P
迪杰斯特拉算法用于求解一个有向图(也可以是无向图,无向图是有向图的一种特例)的一个点(称之为原点)到其余各点(称之为周边点)的最短路径问题。算法构思很是巧妙(我这么认为),简直达到了“无心插柳柳成荫”的境界。算法本身并不是按照我们的思维习惯——求解从原点到第一个点的最短路径,再到第二个点的最短路径,直至最后求解完成到第n个点的最短路径,而是求解从原点出发的各有向路径的从小到大的排列(如果这个有向图中有环1-2-3-1算法岂不是永无终结之日了??!!),但是算法最终确实得到了从原点到图中其余各点的最短路径,可以说这是个副产品,对于算法的终结条件也应该以求得了原点到图中其余各点的最短路径为宜。清楚了算法的这种巧妙构思后,理解算法本身就不是难题了。
8 |+ |/ z. o$ o+ T4 V 算法把一个图(G)中的点划分成了若干部分:
* r2 S3 @2 ~2 r4 H, { 1):原点(v);
7 V$ t' w. } |, \- I 2):所有周边点(C);9 R+ ?& o' J% s: S5 y
另外有一个辅助集合S,从v到S中的点的最短路径已经求得。S的最初状态是空集。% \ |. S; y3 ?
这样就可以进一步划分图(G):
: n' h* j0 |( T* O 1):原点(v);( J5 S4 ]- p1 i$ p+ Q! j% V
2):已求出v至其最短路径的周边点(S);
% D3 M" \7 R/ P. } v 3):尚未求出v至其最短路径的周边点(Other=C-S);
* w3 Y F+ P+ M; D8 ?. r6 \: n& h 算法的主体思想:" [8 [$ H, _% e, F2 a
A、找到v——Other所有路径中的的最短路径vd=v——d(Other的一个元素);
$ H8 E8 y4 v7 f( R0 a; HB、找到v——S——Other所有路径中的的最短路径vi=v——i(Other的一个元素);2 F; ^3 l6 u& v: P$ q
C、比较vd和vi如果vd<=vi则将d加入S且从Other中删除,否则将i加入S且从Other中删除。
5 d! }" }# Z, `( i4 B0 A重复以上步骤直至Other为空集。
; s( ?3 @1 z6 o. R5 _, @
. [& u4 a* m# j* K& V我们求得的最短路径是升序排列的,那为什么下一条最短路径就存在于v—— 2 v, I# X/ C0 ~/ }- z% @! {; c
7 n) ]! f( i. A |
zan
|