📄 minforedynprog.asv
字号:
function[OptPol,OptObjval]=MinForeDynprog(x,DecisFun,StageObjFun,StateTransFun,ObjFun)
%***************************************************************%
%以下为动态规划的顺序(前向)最小算法,取自文献基于Matlab的动态规划顺序算法的实现.pdf
%基本公式如下:
%顺序算法的优点缺点需要和逆序算法实际地做个比较的
%而且是求最小的算法,如果求最大怎么办?
%***************************************************************%
%其中x是状态变量,一列代表一个阶段状态;
%M-函数DecisFun(k ,x)表示由阶段k的状态变量xk求出相应的允许决策变量;
%M-函数StageObjFun(k ,x ,u)是阶段目标函数;
%M-函数StateTransFun(k ,x ,u)是状态转移函数,其中x是阶段k的某状态变量,
%%而u是相应的决策变量,对于顺序算法而言,在使用状态转移函数时,一般采用其逆函数的形式;
%M-函数ObjFun (v ,f )是第k - 1 阶段及其以前阶段的目标函数,
%%正如基本方程中所描述的那样,第一阶段(初始阶段) 的目标函数通常设为0;
%OptPol由四列构成,OptPol=[ 阶段号; 状态; 决策; 阶段目标函数值];
%OptObjval是一个列向量,各元素分别表示各最优策略对应的最优目标函数值.
%***************************************************************%
%*不懂人家的程序可以一步一步打入command窗口进行实际查看结果,比较直观先理解结果,再去理解实现过程和手法***%
%*当然这是其中的一个办法,从宏观还应该找到其算法和程序流程,同时能找到Nes C语言那样的程序调用语义框架联结结构更好,更易理解*%
step=length(x(1,:));%计算的结果就是x的列数=5
x_isnan=~isnan(x);%使得x_isnan返回由1和0组成的判断x中不为“非数nan”,如果是数值返回1,不是返回0
compar_valm=inf*ones(size(x));%全部置+∞
f_opt=nan*ones(size(x));%原先被写成了man*,全部置为nan,似乎为一张记录所有结果的表?其实目标函数值
d_opt=f_opt;
k=1;
tmp1=find(x_isnan(:,k));%原先把tmp1打成了tmpl了,怪不得老提示变量没定义呢.找出第一列中非零的行数为1
tmp2=length(tmp1);%返回tmp1的列数=1
% 下面这一小段程序干什么用,不清楚啊
for i=1:tmp2
u=nan;
tmp3=feval(StageObjFun,k,x(tmp1(i),k),u);%又把tmp1打成了tmpl了.
f_opt(i,k)=tmp3;%f_opt(i,k)和d_opt(i,k)是代表什么?分布为目标函数和阶段目标函数
d_opt(i,k)=u;
end
for k=2:1:step
tmp4=find(x_isnan(:,k));%tmp4找出x_isnan第二列中不为0的所有行数,组成一个列向量1-500
tmp5=length(tmp4);%tmp5=500
for i=1:tmp5 %i为状态变量x的索引,u为决策变量
u=feval(DecisFun,k,x(i,k));%feval这个函数还是不会用,就是一个返回函数值,那么DecisFun函数的定义有点奇怪
tmp6=length(u);%=500
for j=1:tmp6 %即决策变量u(k阶段加工零件数)索引号
tmp7=feval(StateTransFun,k,x(tmp4(i),k),u(j));%当k=2,i=1,j=1,tmp7=x+u=1+1=2
tmp8=x(:,k-1)-tmp7; %当k=2,j=1,tmp8为500行1列的数组,第一个值为500-2
tmp9=find(tmp8==0);%当k=2,i=1,j=499,tmp7=x+u=1+499=500,tmp8第一个值为0
if~isempty(tmp9)
tmp10=feval(StageObjFun,k,tmp7,u(j)); %
tmp10=feval(ObjFun,tmp10,f_opt(tmp9(1),k-1));% f_opt里边都是非数啊,怎么在比较的时候变成0了呢?
if tmp10<=compar_valm(i,k)
f_opt(i,k)=tmp10;%目标函数值对应决策变量为499,表示第一个车床加工499个
d_opt(i,k)=u(j); %决策变量,此时表示第一台车床加工499个
compar_valm(i,k)=tmp10;
end
end
end
end
end
f=f_opt(:,step);f=f(find(~isnan(f)),1);OptObjval=min(f(:));
OptPol=[];tmpx=[];tmpd=[];tmpf=[];
tmp11=find(f_opt(:,step)==OptObjval);tmp12=length(tmp11);
for i=1:tmp12
tmpd(i)=d_opt(tmp11(i),step);tmpx(i)=x(tmp11(i),step);
tmp13=feval(StateTransFun,step,tmpx(i),tmpd(i));
tmpf(i)=feval(StageObjFun,step,tmp13,tmpd(i));
OptPol(step*(i-1)+step,[1,2,3,4])=[step,tmpx(i),nan,nan];
%注释中的这上下两行的OptPol应该是少一个括号的,但不知道应该放在哪里,原文如此了.
%step和step-1后面的括号说明了OptPol(x,y)这种格式才是正确的.
OptPol(step*(i-1)+step-1,[1,2,3,4])=[step-1,tmp13,tmpd(i),tmpf(i)];
for k=step-1:-1:2
tmpx(i)=tmp13;tmp14=x(:,k)-tmpx(i);tmp15=find(tmp14==0);
if ~isempty(tmp15)
tmpd(i)=d_opt(tmp15(1),k);
end
tmp13=feval(StateTransFun,step,tmpx(i),tmpd(i));%有错,原先参数少一个step
tmpf(i)=feval(StageObjFun,k,tmp13,tmpd(i));
OptPol(step*(i-1)+k-1,[1,2,3,4])=[k-1,tmp13,tmpd(i),tmpf(i)];%k-1后面的括号说明了OptPol(x,y)这种格式才是正确的.
end
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -