如图所示两定点连线上的数字表示距离,确定一条从定点1到定点7的最短路径应该如何做?
直观上有这么一个重要常识如果
为最短路径,则
为从mi出发到m7的最短路线。这一特性即为最优性原理。根据最优性原理,寻找最短路径可以从最后一段开始,用由后向前逐步递推的方法,求出各点到m7点的最短路径,我们来看一下具体求算方法:
由路线图可知mi到m7分三步走。用k表示步数(1 、2 、3):
当k=3,有三个出发点:m4、m5、m6,出发点到下个点的距离记做dk(mi,mj)。出发点到m7的最短距离记做:f3(m4)、f3(m5)、f3(m6),可知:f3(m4)=d3(m4,m7)、f3(m5)=d3(m5,m7)、f3(m6)=d3(m6,m7)值分别为f3(m4)=3,f3(m5)=5,f3(m6)=4;
当k=2,有二个出发点:m2、m3,出发点到m7的最短路径f2(m2)、f2(m3)具体计算方法为:
分别从m2、m3,出发的最短路径为:
当k=1,有一个出发点:m1,则f1(m1)的具体计算公式为:
得出最短路径为f1(m1)=13:
这是比较简单的路径优化问题,如果步数多一点,过冷水就不能做到这么直观的演示求解过程了,问题的解决思路就是这样,我们需要把它做到编程化。
出发点和目的点的选择,代码如下:
if x==1;
x1=[2;3];
elseif x==2;
x1=[4;5];
elseif x==3;
x1=[4;5;6];
elseif (x==4)|(x==5)|(x==6)
x1=7;
elseif x==7;
x1=7;
出发点和目的点之间的距离,代码如下:
dxx1=[5;4;6;3;8;7;6;3;5;4];
xx1=[x==1&x1==2,x==1&x1==3,x==2&x1==4,x==2&x1==5,x==3&x1==4,x==3&x1==5,x==3&x1==6,x==4&x1==7,x==5&x1==7,x==6&x1==7];
v=xx1*dxx1;
阶段和出发点之间的联系:k=4,x=7;k=3,x=[4,5,6];k=2,x=[2,3];k=1,x=[1];可以写成矩阵形式,代码如下:
x=NaN*ones(3,4);
x(1,1)=1;
x(1:2,2)=[2,3];
x(1:3,3)=(4:6)';
x(1,4)=7;
x
x =
1 2 4 7
NaN 3 5 NaN
NaN NaN 6 NaN
总的出发点和目的点之间的距离寻优代码如下:
clear all
%不同阶段对应的出发点
x=NaN*ones(3,3);
x(1,1)=1;x(1:2,2)=[2,3];x(1:3,3)=(4:6)';
v=cell(3,4);v{1,4}=0;v{2,4}=0;v{3,4}=0;%用于储存x,x1之间的距离的原包组,
w=zeros(3,4);%构建用于存储当前出发点到终点的最近距离的矩阵;
for n=1:3;
k=4-n;%倒序阶段
matx_point=x(:,k);
x1=~isnan(matx_point);
m=find(x1==1);
d=matx_point(m);
%判断当前出发点下可到达的下一个出发点
for i=1:length(m);
if d(m(i))==1;
d1=[2;3];
elseif d(m(i))==2;
d1=[4;5];
elseif d(m(i))==3;
d1=[4;5;6];
elseif (d(m(i))==4)|(d(m(i))==5)|(d(m(i))==6);
d1=7;
elseif d(m(i))==7;
d1=7;
end
%计算当前出发点到一下出发点的距离
distan=[5;4;6;3;8;7;6;3;5;4];
dd1=[d(m(i))==1&d1==2,d(m(i))==1&d1==3,d(m(i))==2&d1==4,d(m(i))==2&d1==5,d(m(i))==3&d1==4,d(m(i))==3&d1==5,d(m(i))==3&d1==6,d(m(i))==4&d1==7,d(m(i))==5&d1==7,d(m(i))==6&d1==7];
v{m(i),k}=dd1*distan;
%当前出发点到终点的距离最近距离
l=length(d1);
for j=1:l;
mind(j)=v{m(i),k}(j)+ w(j,k+1);
end
w(i,k)=min(mind);
[positioni,poxitionj]=find(min(mind)==mind);
rout(i,k)=d1(poxitionj);
clear mind;
end
end
%最优路线距离
opt_distance=w(1,1)
%最优路线方案
rout(1,1);[u1,s1]=find(x==rout(1,1));
rout(u1,s1);[u2,s2]=find(x==rout(u1,s1));
rout(u2,s2);
opt_path=[1,rout(1,1),rout(u1,s1),rout(u2,s2)]
该代码是根据理论叙述过冷水写出来的算法,参数设置和特定目标实现的方法和奇怪。还请大家见谅,动态规划实际是有比较成熟的算法代码的,可用的场合也比较广泛,在此过冷水给出用动态规划逆顺序算法的程序,后期会对程序进行分析讲解。对路径寻优感兴趣的可以和过冷水交流,深入理解路径寻优的问题。
路径寻优参考代码:
clear all
x=NaN*ones(3,4);
x(1,1)=1;
x(1:2,2)=[2,3];
x(1:3,3)=(4:6)';
x(1,4)=7;
x
[p,f]=dynprog(x,@DecisFun,@SubObjfun,@TransFun)%f:最优解;p:最优指标
dynprog.m
function [p_opt fval]=dynprog(x,DecisFun,SubObjFun,TransFun,ObjFun)
k=length(x(1,:));
x_isnan=~isnan(x);
t_vub=inf;
t_vubm=inf*ones(size(x));
f_opt=nan*ones(size(x));
d_opt=f_opt;
%计算终端
tmp1=find(x_isnan(:,k));
tmp2=length(tmp1);
for i=1:tmp2
u=feval(DecisFun,k,x(i,k));
tmp3=length(u);
for j=1:tmp3;
tmp=feval(SubObjFun,k,x(tmp1(i),k),u(j));
if tmp<=t_vub;
f_opt(i,k)=tmp;
d_opt(i,k)=u(j);
t_vub=tmp;
end;
end;
end;
for ii=k-1:-1:1;
tmp10=find(x_isnan(:,ii));
tmp20=length(tmp10);
for i=1:tmp20;
u=feval(DecisFun,ii,x(i,ii));
tmp30=length(u);
for j=1:tmp30;
tmp00=feval(SubObjFun,ii,x(tmp10(i),ii),u(j));
tmp40=feval(TransFun,ii,x(tmp10(i),ii),u(j));
tmp50=x(:,ii+1)-tmp40;
tmp60=find(tmp50==0);
if~isempty(tmp60);
if nargin<5,
tmp00=tmp00+f_opt(tmp60(1),ii+1);
else
tmp00=feval(ObjFun,tmp00,f_opt(tmp60(1),ii+1));
end
if tmp00<=t_vubm(i,ii);
f_opt(i,ii)=tmp00;
d_opt(i,ii)=u(j);
t_vubm(i,ii)=tmp00;
end
end
end
end
end
fval=f_opt(tmp1,1);
fval=fval(find(~isnan(fval)),1);
%记录最优决策、最优线性轨线和相应指标函数
p_opt=[];tmpx=[];tmpd=[];tmpf=[];
tmp0=find(x_isnan(:,1));
tmp01=length(tmp0);
for i=1:tmp01;
tmpd(i)=d_opt(tmp0(i),1);
tmpx(i)=x(tmp0(i),1);
tmpf(i)=feval(SubObjFun,1,tmpx(i),tmpd(i));
p_opt(k*(i-1)+1,[1,2,3,4])=[1,tmpx(i),tmpd(i),tmpf(i)];
for ii=2:k;
tmpx(i)=feval(TransFun,ii-1,tmpx(i),tmpd(i));
tmp1=x(:,ii)-tmpx(i);
tmp2=find(tmp1==0);
if~isempty(tmp2);
tmpd(i)=d_opt(tmp2(1),ii);
end;
tmpf(i)=feval(SubObjFun,ii, tmpx(i),tmpd(i));
p_opt(k*(i-1)+ii,[1,2,3,4])=[ii,tmpx(i),tmpd(i),tmpf(i)];
end
end
DecisFun.m
function x1=DecisFun(k,x)
if x==1;
x1=[2;3];
elseif x==2;
x1=[4;5];
elseif x==3;
x1=[4;5;6];
elseif (x==4)|(x==5)|(x==6)
x1=7;
elseif x==7;
x1=7;
end
SubObjfun.m
function x1=DecisFun(k,x)
if x==1;
x1=[2;3];
elseif x==2;
x1=[4;5];
elseif x==3;
x1=[4;5;6];
elseif (x==4)|(x==5)|(x==6)
x1=7;
elseif x==7;
x1=7;
end
TransFun.m
function y=TransFun(k,x,x1)
y=x1;
未经授权擅自搬运抄袭的,必将追究其责任!