动态规划的Matlab实现和实例分析 摘自matlabsky
2013-08-27 19:40阅读:
动态规划是解决多阶段决策过程最优化问题的一种方法.
该方法是由美国数学家贝尔曼(R.Bellman)等人在2O世纪50年代初提出的.他们针对多阶段决策问题的特点,提出了解决这类问题的最优化原理,并成功地解决了生产管理、资源分配等方面的许多实际题,从而建立了运筹学的一个新分支——动态规划.
动态规划是现代企业管理中的一种重要决策方法,可用于解决最优路径、资源分配、生产计划与库存、投资、装载、排序等问题,还可用于生产过程的最优控制等.由于它有独特的解题思路,因而在处理某些优化问题时,比线性规划或非线性规划方法更有效.
而Matlab是一个功能强大的用于基于矩阵运算的强大数值计算软件,将Matlab语言应用到动态规划中去,对实际问题进行程序设计和计算,可以达到计算简便的目的.
一、动态规划基本概念
使用动态规划方法解决多阶段决策问题,首先要将实际问题写成动态规划模型,此时要用到以下概念:
1)阶段
将所给问题的过程,按时间或空间特征分解成若干互相联系的阶段,以便按次序去求解每阶段的解,每个阶段就是一个子问题,常用字母k表示阶段变量.
2)状态
各阶段开始时的客观条件叫做状态.描述各阶段状态的变量称为状态变量,常用sk表示第k阶段的状态变量.状态变量sk的取值集合称为状态集合,用sk表示.
3)决策
当各段的状态取定以后,就可以作出不同的决策(或选择),从而确定下一阶段的状态,这种决定称为决策.表示决策的变量称为决策变量,常用uk(sk)表示第k阶段当状态为sk时的决策变量.在实际问题中,决策变量的取值往往限制在一定范围内,称此范围为允许决策集合,常用Dk(sk)表示第k阶段从状态sk出发的允许决策集合,显然有“uk∈Dk(sk).
4)策略
一个由每个阶段的决策按顺序组成的集合称为策略,用p表示,即p(s1)={u1(s1),u2(s2),.......,un(sn),}。一个n阶段决策过程,从1到n叫作问题的原过程.对于任意给定的k(1≤k≤n),从第k阶段状态sk到第n阶段状态sn的过程称为原过程的一个后部子过程.后部子过程的策略记为pk(sk)={uk(sk),uk+1(sk+1),......,un(sn)},在实际问题中,可供选择的策略有一定的范围,此范围成为允许策略集合。允许策略集合中达到最优效果的策略成为最优策略
5)状态转移
动态规划中本阶段往往是上一阶段状态和上一阶段的决策进行综合的结果.如果给定了第k段的状态sk,且该阶段决策为uk(sk),则第k+1段的状态sk+1也就完全确定.它们的关系可表示为:
sk+1=Tk(sk,uk)
由于上式表示了由k阶段到k+1阶段的状态转移规律,所以称该式为状态转移方程.
6)指标函数
用于衡量所选定策略优劣的数量指标称为指标函数.一个n阶段决策过程,从1到n叫作问题的原过程.对于任意一个给定的k(1≤k≤n),从第k阶段到第n阶段的过程称为原过程的一个后部子过程。V1,n(s1,p1,n)表示初始状态为s1采用策略p1,n时原过程的指标函数值。而Vk,n(sk,pk,n)表示在第k阶段,状态为sk采用策略pk,n时后部子过程的指标函数值.最优指标函数记为fk(sk),它表示从第k阶段状态sk采用最优策略pk,n到过程终止时的最佳效益值.fk(sk)与Vk,n(sk,pk,n)间的关系为:
fk(sk)=Vk,n(sk,pk,n)=optimize
Vk,n(sk,pk,n)
当k=1时,f1(s1)就是从初始状态s1到全过程结束的整体最优函数.
二、动态规划基本思路
1)将多阶段决策过程划分阶段,恰当地选择状态变量、决策变量以定义最优指标函数,从而把问题化成一族同类型的子问题,然后逐个求解.
2)求解时从边界条件开始,逆序过程行进,逐段递推寻优.在每一个子问题求解时,都要使用它前面已求出的子问题的最优结果.最后一个子问题的最优解,就是整个问题的最优解.
3)动态规划方法是既将当前一段与未来各段分开,又把当前效益和未来效益结合起来考虑的一种最优化方法,因此每段的最优决策选取是从全局考虑的,与该段的最优选择一般是不同的.
三、动态规划函数使用说明
由于我们的目的是使用动态规划解题,而不是要我们直接编写动态规划的MATLAB程序,那我们下面直接给出一个现成的动态规划的MATLAB源代码,这里不讨论它到底是是如何运行的,我们只是说明下该函数如何使用
- function
[p_opt,fval]=dynprog(x,DecisFun,ObjFun,TransFun)
- %
自由始端和终端的动态规划,求指标函数最小值的逆序算法递归计算程序
- %输入参数
- %
x各阶段状态变量的可能取值,第k列代表第k阶段状态变量可能取值
- %
DecisFun(k,x)决策函数,由阶段k的状态变量x求出相应的允许决策变量
- %
ObjFun(k,x,u)阶段指标函数
- %
TransFun(k,x,u)状态转移函数,其中x是阶段k的某状态变量,u是相应的决策变量
- %输出参数
- %
p_opt动态规划的规划过程,p_opt=[阶段序号,状态变量,决策变量,指标函数]
- %
fval总目标函数值,是一个列向量,第i元素代表第一个状态变量取第i个可能值时的总目标
复制代码
该函数的下载参见【数学建模工具箱】http://www.matlabsky.com/thread-221-1-2.html
四、动态规划实例分析
某公司拟将某种设备5台分配给甲、乙、丙3个工厂,各工厂利润与设备数量之间的关系如下表所示,问这5台设备如何分配使3个工厂的总利润为最大?
应用动态规划方法分析如下
1.阶段k
将问题按工厂分为3个阶段,k=1,2,3
2.状态sk
给第k个工厂分配前拥有的设备台数,显然s1=5
3.决策uk
分配给第k个工厂的设备台数,显然
分给第一个工厂可以0到s1台之间
分给第二个工厂也可以0到s2台之间
分给第三个工厂的为s2台
- function
u=decisfun(k,s,u)
- if k==3
- u=s;
- else
- u=0:s;
- end
复制代码
4.状态转移Tk
前后两个状态之间的关系如下
s2=s1-u1,s3=s2-u2
- function
s_next=transfun(k,s,u)
- s_next=s-u
复制代码
5.阶段指标Vk
第k阶段的指标函数,表示配给第k个工厂uk台设备所获得的利益,显然
Vk=w(uk,k)
- function
V=subobjfun(k,s,u)
- w=[0 0 0
- 3 5 4
- 7 10 6
- 9 11 11
- 12 11 12
- 13 11 12];
-
w=-w;%由于函数只能求最小值,现在求最大值,故取符号
-
%第k阶段,决策变量为u时,对应的目标值
- V=([0 1 2 3 4
5]==u)*w(:,k);%或者直接使用V=w(u,k)
复制代码
6.各阶段状态变量可能取值
由已知,我们容易知道
s1={5}
s2={0,1,2,3,4,5}
s3={0,1,2,3,4,5}
故
-
s=nan*ones(6,3);%没有取值的地方使用nan代替
- s(1,1)=5;
- s(:,2)=[0 1 2 3 4
5]’;
- s(:,3)=[0 1 2 3 4
5]’;
复制代码
根据上面的分析,我们编写程序如下
- function
matlabsky
-
%动态规划函数求解问题演示实例
- %by dynamic
- %see also
http://www.matlabsky.com
- 08.12.23
- %
-
%计算各状态变量可能取值,第k列代表第k个状态变量的可能取值,没有的使用NaN代替
-
s=nan*ones(6,3);
- s(1,1)=5;
- s(:,2)=[0 1 2 3 4
5]';
- s(:,3)=[0 1 2 3 4
5]';
-
%直接调用dynprg函数
-
[p_opt,fval]=dynprog(s,@DecisFun,@ObjFun,@TransFun)
- function
u=DecisFun(k,s,u)
- %决策函数
- if k==3
-
u=s;
- else
-
u=0:s;
- end
- function
s_next=TransFun(k,s,u)
- %状态转移函数
- s_next=s-u;
- function
V=ObjFun(k,s,u)
- %阶段目标函数
- w=[0 0 0
- 3 5 4
- 7 10 6
- 9 11 11
- 12 11 12
- 13 11 12];
-
w=-w;%由于函数只能求最小值,现在求最大值,故取符号
-
%第k阶段,决策变量为u时,对应的目标值
- V=([0 1 2 3 4
5]==u)*w(:,k);%或者直接使用V=w(u,k)
复制代码
运行结果如下
- p_opt =
-
1 5
2 -7
-
2 3
2 -10
-
3 1
1 -4
- fval =
-
-21
-
NaN
-
NaN
-
NaN
-
NaN
- NaN
复制代码
这个运行结果解读如下,我们要一行一行的解读
对于p_opt:
第一阶段,状态变量为5,决策变量为2,阶段指标为-7,也就是说第一阶段时有5台设备,分配给第一个工厂2台,该工厂的利益为-7
第二阶段,状态变量为3,决策变量为2,阶段指标为-10,也就是说第二阶段时有3台设备,分配给第二个工厂2台,该工厂的利益为-10
第三阶段,状态变量为1,决策变量为1,阶段指标为-4,也就是说第三阶段时有1台设备,分配给第三个工厂1台,该工厂的利益为-4
对于fval:
总指标值为-21=-7-10-4,也就是说按上面的最优策略,将最大获利21
后面的那些NaN是由于第一个状态变量的可能取值我们只是输入了5,而其他可能值都是用NaN的,故没有结果
当然第一个状态变量的可能取多个值,dynprog可以求解第一个状态变量多取值的情况。可是根据该题实际我们只有一个5。下面我们试试,假如s={4
5}的运行结果
-
%计算各状态变量可能取值,第k列代表第k个状态变量的可能取值,没有的使用NaN代替
-
s=nan*ones(6,3);
-
s(1:2,1)=[4,5];
- s(:,2)=[0 1 2 3 4
5]';
- s(:,3)=[0 1 2 3 4
5]';
-
%直接调用dynprg函数
-
[p_opt,fval]=dynprog(s,@DecisFun,@ObjFun,@TransFun)
复制代码
运行结果如下,至于结果的解读,大家可以根据dynprog函数的说明试试看看,能否明白
如果没法理解,可以与我一起探讨下matlabsky@gmail.com
- p_opt =
-
1 4
2 -7
-
2 2
2 -10
-
3 0
0 0
-
1 5
2 -7
-
2 3
2 -10
-
3 1
1 -4
- fval =
-
-17
-
-21
-
NaN
-
NaN
-
NaN
- NaN
复制代码
摘自matlabsky:参考网址:
http://www.matlabsky.com/thread-644-1-1.html