基于MATLAB求解最短路问题.docx
《基于MATLAB求解最短路问题.docx》由会员分享,可在线阅读,更多相关《基于MATLAB求解最短路问题.docx(8页珍藏版)》请在冰豆网上搜索。
基于MATLAB求解最短路问题
1.引言
MATLAB和Mathematica、Maple并称为三大数学软件。
它在数学类科技应用软件中在数值计算方面首屈一指。
通过本学期的学习了解和上机实践,已经初步掌握使用MATLAB工具解决实际问题的能力。
结合运筹学课程的学习,我考虑使用MATLAB求解最短路问题,而在所有求解最短路的方法中,Dijkstra算法是最为经典的一种,因此本文主要解决在MATLAB环境下使用Dijkstra算法求解最短路。
1.1提出问题
设6个城市v1,v2,......,v6之间的一个公路网(图1)每条公路为图中的边,边上的权数表示该段公路的长度(单位:
百公里),设你处在城市v1,那么从v1到v6应选择哪一路径使你的费用最省。
1.2分析问题
这属于一个典型的求解最短路的问题,图中顶点代表六个城市,边上的权数表示该段公路的长度,题目所求为从v1到v6、的一条费用最省的路径,我们假设所需费用仅与路径长短有关,因此求费用最省的路径即求权值最小的路径。
网络图中各权值均为正,可以使用Dijkstra算法。
1.3数据整理
将网络图中各边的权作如下整理以方便程序运行
W(1,2)=5;W(2,1)=5;
W(1,3)=2;W(3,1)=2;
W(2,3)=1;W(3,2)=1;
W(2,4)=5;W(4,2)=5;
W(2,5)=5;W(5,2)=5;
W(3,4)=8;W(4,3)=8;
W(3,5)=10;W(5,3)=10;
W(4,5)=2;W(5,4)=2;
W(4,6)=5;W(6,4)=5;
W(5,6)=2;W(6,5)=2;
2.数学原理
2.1Dijkstra算法介绍
Dijkstra算法思想为:
设G=(V,E)是一个带权有向图(也可以是无向图,无向图是有向图的特例),把图中顶点集合V分成两组:
第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径,就将其加入到集合S中,直到全部顶点都加入到S中,算法就结束了);第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。
在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。
此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。
其步骤主要有:
第一,初始时,S只包含源点,即S={顶点},v的距离为0。
U包含除v外的其他顶点,U中顶点u距离为边上的权(若v与u有边)或(若u不是v的出边邻接点)。
第二,从U中选取一个距离v最小的顶点k,把k加入S中(该选定的距离就是v到k的最短路径长度)。
第三,以k为新考虑的中间点,修改U中各顶点的距离;若从源点v到顶点u的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值的顶点k的距离加上边上的权。
第四,重复步骤第二步和第三步直到所有顶点都包含在S中。
3.程序设计
function[c0,c,path0,path]=dijkstra(s,t,C,flag)
s=floor(s);
t=floor(t);
n=size(C,1);
label=ones(1,n)*inf;
label(s)=0;
S=[s];
Sbar=[1:
s-1,s+1:
n];
c0=0;
path=zeros(n,n);
path(:
1)=s;
c=ones(1,n)*inf;
parent=zeros(1,n);
i=1;%numberofpointsinpointsetS.
whilei%foreachpointinSbar,replacelabel(Sbar(j))by
%min(label(Sbar(j)),label(S(k))+C(S(k),Sbar(j)))
forj=1:
n-i
fork=1:
i
iflabel(Sbar(j))>label(S(k))+C(S(k),Sbar(j))
label(Sbar(j))=label(S(k))+C(S(k),Sbar(j));
parent(Sbar(j))=S(k);
end
end
end
%Findtheminmallabel(j),j\inSbar.
temp=label(Sbar
(1));
son=1;
forj=2:
n-i
iflabel(Sbar(j))temp=label(Sbar(j));
son=j;
end
end
%updatethepointsetSandSbar
S=[S,Sbar(son)];
Sbar=[Sbar(1:
son-1),Sbar(son+1:
n-i)];
i=i+1;
%ifflag==1,justoutputtheshortestpathbetweensandt.
ifflag==1&&S(i)==t
son=t;
temp_path=[son];
ifson~=s
whileparent(son)~=s
son=parent(son);
temp_path=[temp_path,son];
end
temp_path=[temp_path,s];
end
temp_path=fliplr(temp_path);
m=size(temp_path,2);
path0(1:
m)=temp_path;
c_temp=0;
forj=1:
m-1
c_temp=c_temp+C(temp_path(j),temp_path(j+1));
end
c0=c_temp;
path(t,1:
m)=path0;
c(t)=c0;
return
end
end
%Formtheoutputresults
fori=1:
n
son=i;
temp_path=[son];
ifson~=s
whileparent(son)~=s
son=parent(son);
temp_path=[temp_path,son];
end
temp_path=[temp_path,s];
end
temp_path=fliplr(temp_path);
m=size(temp_path,2);
path(i,1:
m)=temp_path;
c_temp=0;
forj=1:
m-1
c_temp=c_temp+C(temp_path(j),temp_path(j+1));
end
c(i)=c_temp;
c0=c(t);
path0=path(t,:
);
end
return
4.结果分析
4.1运行程序
clc
s=1;
t=6;
flag=1;
W=ones(9,9)*inf;%
fori=1:
9
W(i,i)=0;
end
W(1,2)=5;W(2,1)=5;
W(1,3)=2;W(3,1)=2;
W(2,3)=1;W(3,2)=1;
W(2,4)=5;W(4,2)=5;
W(2,5)=5;W(5,2)=5;
W(3,4)=8;W(4,3)=8;
W(3,5)=10;W(5,3)=10;
W(4,5)=2;W(5,4)=2;
W(4,6)=5;W(6,4)=5;
W(5,6)=2;W(6,5)=2;
[c0,c,path0,path]=dijkstra(s,t,W,flag);
c0
path0
4.2运行结果
4.3结果分析
由运行结果可知,从V1到V6的最短路径长度为10,路径为:
V1->V3->V2->V5->V6,结合网络图进行验证,所求即为最短路。
并且利用上述程序还可求得网络中任意两点之间的最短路径。
5.学习体会
MATLAB是美国MathWorks公司出品的商业数学软件,用于算法开发、数据可视化、数据分析以及数值计算的高级技术计算语言和交互式环境,主要包括MATLAB和Simulink两大部分。
MATLAB是matrix&laboratory两个词的组合,意为矩阵工厂(矩阵实验室)。
是由美国mathworks公司发布的主要面对科学计算、可视化以及交互式程序设计的高科技计算环境。
它将数值分析、矩阵计算、科学数据可视化以及非线性动态系统的建模和仿真等诸多强大功能集成在一个易于使用的视窗环境中,为科学研究、工程设计以及必须进行有效数值计算的众多科学领域提供了一种全面的解决方案,并在很大程度上摆脱了传统非交互式程序设计语言(如C、Fortran)的编辑模式,代表了当今国际科学计算软件的先进水平。
Matlab的学习是在运筹学之后开始的,虽然是作为选修课,也只安排了短短的10次课,但从一开始学习,我就抱着要掌握好这个工具的态度上课,因为不管是数学建模还是运筹学中,都可以用到它解决很多实际问题。
课堂上教员给我们讲解了软件的基本操作并介绍了大量常用的命令,通过理论学习和上机实践操作,慢慢的从开始的完全不懂渐渐能够编写一些简单的M文件解决一些应用题,其中的成就感是相当令人欣慰的。
虽然在此之前我们还学过C语言、C++和数据库,也可以用它们来编程解题,但相比之下,使用MATLAB要简单得多,同样的一个问题,用编程的方法可能需要编写很多条代码,在这个软件中却可以轻松实现。
“师傅领进门,修行靠个人”,受限于开课课时,教员不可能给我们做太过深入的教学,因此要想学好这个软件,最重要的还是靠自己课下的探索,任何工具性的东西都是这样,只有练熟才了生巧。
对提高matlab编程能力的方法,我想主要有以下三个:
1、查help
在第一节课教员就向我们介绍了help命令,在学习过程中,时常遇到一些不知道的关键字,这时候只要通过help命令就可以找到该关键字的介绍,并且还有部分举例,非常有助于理解程序。
2、多上论坛,搜索帖子、发帖询问
网上有很多关于MATLAB的贴吧和论坛,许多学习这个程序的人都在这里交流,有初学者也有高手,上论坛的一个好处就是可以知道别人在学习过程中都遇到了一些什么问题,他们是怎么解决的,有什么好的学习经验和方法可以供自己借鉴,甚至也可以自己发帖和别人交流,请教高手解答自己的困惑等等