动态规划

动态规划

本文介绍了动态规划的基本思想和基本步骤,经过实例研究了利用动态规划设计算法的具体途径,讨论了动态规划的一些实现技巧,并将动态规划和其余一些算法做了比较,最后还简单介绍了动态规划的数学理论基础和当前最新的研究成果。html

引言——由一个问题引出的算法算法

考虑如下问题express

[例1]最短路径问题数组

现有一张地图,各结点表明城市,两结点间连线表明道路,线上数字表示城市间的距离。如图1所示,试找出从结点A到结点E的最短距离。网络

图 1数据结构

咱们能够用深度优先搜索法来解决此问题,该问题的递归式为app

其中是与v相邻的节点的集合,w(v,u)表示从v到u的边的长度。框架

具体算法以下:ide

function MinDistance(v):integer;函数

begin

 if v=E then return 0

  else

   begin

    min:=maxint;

    for 全部没有访问过的节点i do

     if v和i相邻 then 

      begin

        标记i访问过了;

        t:=v到i的距离+MinDistance(i);

        标记i未访问过;        

        if t<min then min=t;

      end;  

   end;

end;

开始时标记全部的顶点未访问过,MinDistance(A)就是从A到E的最短距离。

这个程序的效率如何呢?咱们能够看到,每次除了已经访问过的城市外,其余城市都要访问,因此时间复杂度为O(n!),这是一个“指数级”的算法,那么,还有没有更好的算法呢?

首先,咱们来观察一下这个算法。在求从B1到E的最短距离的时候,先求出从C2到E的最短距离;而在求从B2到E的最短距离的时候,又求了一遍从 C2到E的最短距离。也就是说,从C2到E的最短距离咱们求了两遍。一样能够发现,在求从C一、C2到E的最短距离的过程当中,从D1到E的最短距离也被求 了两遍。而在整个程序中,从D1到E的最短距离被求了四遍。若是在求解的过程当中,同时将求得的最短距离"记录在案",随时调用,就能够避免这种状况。于 是,能够改进该算法,将每次求出的从v到E的最短距离记录下来,在算法中递归地求MinDistance(v)时先检查之前是否已经求过了 MinDistance(v),若是求过了则不用从新求一遍,只要查找之前的记录就能够了。这样,因为全部的点有n个,所以不一样的状态数目有n个,该算法 的数量级为O(n)。

更进一步,能够将这种递归改成递推,这样能够减小递归调用的开销。

请看图1,能够发现,A只和Bi相邻,Bi只和Ci相邻,...,依此类推。这样,咱们能够将原问题的解决过程划分为4个阶段,设S1={A},S2={B1,B2},S3={C1,C2,C3,C4},S4={D1,D2,D3},Fk(u)表示从Sk中的点u到E的最短距离,则

而且有边界条件

显然能够递推地求出F1(A),也就是从A到E的最短距离。这种算法的复杂度为O(n),由于全部的状态总数(节点总数)为n,对每一个状态都只要遍历一次,并且程序很简洁。

具体算法以下:

procedure DynamicProgramming;

 begin

  F5[E]:=0;

  for i:=4 downto 1 do

     for each u ∈Sk do

      begin

       Fk[u]:=无穷大;

       for each v∈Sk+1∩δ(u) do

         if Fk[u]>w(u,v)+Fk+1[v] then Fk[u]:=w(u,v)+Fk+1[v];

   end;

  输出F1[A]; 

 end;

这种高效算法,就是动态规划算法。

动态规划的基本概念

动态规划的发展及研究内容

动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法。20世纪50年代初美国数学家R.E.Bellman等人在研究多阶段决策过程(multistep decision process)的优化问题时,提出了著名的最优化原理(principle of optimality),把多阶段过程转化为一系列单阶段问题,逐个求解,创立了解决这类过程优化问题的新方法——动态规划。1957年出版了他的名著Dynamic Programming,这是该领域的第一本著做。

动态规划问世以来,在经济管理、生产调度、工程技术和最优控制等方面获得了普遍的应用。例如最短路线、库存管理、资源分配、设备更新、排序、装载等问题,用动态规划方法比用其它方法求解更为方便。

虽然动态规划主要用于求解以时间划分阶段的动态过程的优化问题,可是一些与时间无关的静态规划(如线性规划、非线性规划),只要人为地引进时间因素,把它视为多阶段决策过程,也能够用动态规划方法方便地求解。

多阶段决策问题

多阶段决策过程,是指这样的一类特殊的活动过程,问题能够按时间顺序分解成若干相互联系的阶段,在每个阶段都要作出决策,所有过程的决策是一个决策序列。要使整个活动的整体效果达到最优的问题,称为多阶段决策问题。

例1是一个多阶段决策问题的例子,下面是另外一个多阶段决策问题的例子:

[例2] 生产计划问题

工厂生产某种产品,每单位(千件)的成本为1(千元),每次开工的固定成本为3(千元),工厂每季度的最大生产能力为6(千件)。经调查,市场 对该产品的需求量第1、2、3、四季度分别为 2,3,2,4(千件)。若是工厂在第1、二季度将整年的需求都生产出来,天然能够下降成本(少付固定成本费),可是对于第3、四季度才能上市的产品需付 存储费,每季每千件的存储费为0.5(千元)。还规定年初和年底这种产品均无库存。试制订一个生产计划,即安排每一个季度的产量,使一年的总费用(生产成本 和存储费)最少。

决策过程的分类

根据过程的时间变量是离散的仍是连续的,分为离散时间决策过程(discrete-time decision process),即多阶段决策过程和连续时间决策过程(continuous-time decision process);根据过程的演变是肯定的仍是随机的,分为肯定性决策过程(deterministic decision process)和随机性决策过程(stochastic decision process),其中应用最广的是肯定性多阶段决策过程。

动态规划模型的基本要素

一个多阶段决策过程最优化问题的动态规划模型一般包含如下要素:

1.阶段

阶段(step)是对整个过程的天然划分。一般根据时间顺序或空间特征来划分阶段,以便按阶段的次序解优化问题。阶段变量通常用k=1,2,..,n表示。在例1中由A出发为k=1,由Bi(i=1,2)出发为k=2,依此下去从Di(i=1,2,3)出发为k=4,共n=4个阶段。在例2中按照第1、2、3、四季度分为k=1,2,3,4,共4个阶段。

2.状态

状态(state)表示每一个阶段开始时过程所处的天然情况。它应该可以描述过程的特征而且具备无后向性,即当某阶段的状态给定时,这个阶段之后过程的演变与该阶段之前各阶段的状态无关,即每一个状态都是过去历史的一个完整总结。一般还要求状态是直接或间接能够观测的。

描述状态的变量称状态变量(state variable)。变量容许取值的范围称容许状态集合(set of admissible states)。用xk表示第k阶段的状态变量,它能够是一个数或一个向量。用Xk表示第k阶段的容许状态集合。在例1中x2可取B1,B2,X2={B1,B2}。

n个阶段的决策过程有n+1个状态变量,xn+1表示xn演变的结果,在例1中x5取E。

根据过程演变的具体状况,状态变量能够是离散的或连续的。为了计算的方便有时将连续变量离散化;为了分析的方便有时又将离散变量视为连续的。

状态变量简称为状态。

3.决策

当一个阶段的状态肯定后,能够做出各类选择从而演变到下一阶段的某个状态,这种选择手段称为决策(decision),在最优控制问题中也称为控制(control)。

描述决策的变量称决策变量(decision variable)。变量容许取值的范围称容许决策集合(set of admissible decisions)。用uk(xk)表示第k阶段处于状态xk时的决策变量,它是xk的函数,用Uk(xk)表示了xk的容许决策集合。在例1中u2(B1)可取C1,C2,C3。

决策变量简称决策。

4.策略

决策组成的序列称为策略(policy)。由初始状态x1开始的全过程的策略记做p1n(x1),即p1n(x1)={u1(x1),u2(x2),...,un(xn)}。由第k阶段的状态xk开始到终止状态的后部子过程的策略记做pkn(xk),即pkn(xk)={uk(xk),uk+1(xk+1),...,un(xn)}。相似地,由第k到第j阶段的子过程的策略记做pkj(xk)={uk(xk),uk+1(xk+1),...,uj(xj)}。对于每个阶段k的某一给定的状态xk,可供选择的策略pkj(xk)有必定的范围,称为容许策略集合(set of admissible policies),用P1n(x1),Pkn(xk),Pkj(xk)表示。

5.状态转移方程

在肯定性过程当中,一旦某阶段的状态和决策为已知,下阶段的状态便彻底肯定。用状态转移方程(equation of state)表示这种演变规律,写做

例1中状态转移方程为:xk+1=uk(xk)

6.指标函数和最优值函数

指标函数(objective function)是衡量过程优劣的数量指标,它是关于策略的数量函数,从阶段k到阶段n的指标函数用Vkn(xk,pkn(xk))表示,k=1,2,...,n。

可以用动态规划解决的问题的指标函数应具备可分离性,即Vkn可表为xk,uk,Vk+1 n 的函数,记为:

其中函数是一个关于变量Vk+1 n单调递增的函数。这一性质保证了最优化原理(principle of optimality)的成立,是动态规划的适用前提。

过程在第j 阶段的阶段指标取决于状态xj和决策uj,用vj(xj,uj)表示。阶段k到阶段n的指标由vj(j=k,k+1,..n)组成,常见的形式有:

阶段指标之和,即

阶段指标之积,即

阶段指标之极大(或极小),即

这些形式下第k到第j阶段子过程的指标函数为Vkj(xk,uk,xk+1,...,xj+1)。能够发现,上述(3)-(5)三个指标函数的形式都知足最优性原理。在例1中指标函数为(3)的形式,其中vj(xj,uj)是边<xj,uj(xj)>的权(边的长度),uj(xj)表示从xj出发根据决策uj(xj)下一步所到达的节点。

根据状态转移方程,指标函数Vkn还能够表示为状态xk和策略pkn的函数,即Vkn(xk,pkn)。在xk给定时指标函数Vkn对pkn的最优值称为最优值函数(optimal value function),记做fk(xk),即

其中opt可根据具体状况取max或min。上式的意义是,对于某个阶段k的某个状态xk,从该阶段k到最终目标阶段n的最优指标函数值等于从xk出发取遍全部能策略pkn所获得的最优指标值中最优的一个。

7.最优策略和最优轨线

使指标函数Vkn达到最优值的策略是从k开始的后部子过程的最优策略,记做pkn*={uk*,..un*},p1n*又是全过程的最优策略,简称最优策略(optimal policy)。从初始状态x1(=x1*)出发,过程按照p1n*和状态转移方程演变所经历的状态序列{x1*,x2*,..,xn+1*}称最优轨线(optimal trajectory)。

动态规划的基本定理和基本方程

动态规划发展的早期阶段,从简单逻辑出发给出了所谓最优性原理,而后在最优策略存在的前提下导出基本方程,再由这个方程求解最优策略。后来在动态规划的应用过程当中发现,最优性原理不是对任何决策过程广泛成立,它与基本方程不是无条件等价,两者之间也不存在任何肯定的蕴含关系。基本方程在动态规划中起着更为本质的做用。

[基本定理]

对于初始状态x1∈X1,策略p1n*={u1*,..un*}是最优策略的充要条件是对于任意的k,1<k<=n,有

[推论]

若p1n*∈P1n(x1)是最优策略,则对于任意的k,1<k<n,它的子策略pkn*对于由x1和p1,k-1*肯定的以xk*为起点的第k到n后部子过程而言,也是最优策略。

上述推论称为最优化原理,它给出了最优策略的必要条件,一般略述为:不论过去的状态和决策如何,对于前面的决策造成的当前的状态而言,余下的各个决策一定构成最优策略。

根据基本定理的推论能够获得动态规划的基本方程:

其中是决策过程的终端条件,为一个已知函数。当xn+1只取固定的状态时称固定终端;当xn+1可在终端集合Xn+1中变更时称自由终端。最终要求的最优指标函数知足(10)式:

(9)式是一个递归公式,若是目标状态肯定,固然能够直接利用该公式递归求出最优值(这种递归方法将在后文介绍,称做备忘录法),可是通常在实际应用中咱们一般将该递归公式改成递推公式求解,这样通常效率会更高一些。

动态规划的适用条件

任何思想方法都有必定的局限性,超出了特定条件,它就失去了做用。一样,动态规划也并非万能的。适用动态规划的问题必须知足最优化原理和无后效性。

1.最优化原理(最优子结构性质)

最优化原理可这样阐述:一个最优化策略具备这样的性质,不论过去状态和决策如何,对前面的决策所造成的状态而言,余下的诸决策必须构成最优策略。简而言之,一个最优化策略的子策略老是最优的。一个问题知足最优化原理又称其具备最优子结构性质。

图2

例如图2中,若路线I和J是A到C的最优路径,则根据最优化原理,路线J必是从B到C的最优路线。这可用反证法证实:假设有另外一路径J'是B到C的最优路径,则A到C的路线取I和J'比I和J更优,矛盾。从而证实J'必是B到C的最优路径。

最优化原理是动态规划的基础,任何问题,若是失去了最优化原理的支持,就不可能用动态规划方法计算。动态规划的最优化理在其指标函数的可分离性和单调性中获得体现。根据最优化原理导出的动态规划基本方程是解决一切动态规划问题的基本方法。

能够看出,例1是知足最优化原理的。

2.无后向性

将各阶段按照必定的次序排列好以后,对于某个给定的阶段状态,它之前各阶段的状态没法直接影响它将来的决策,而只能经过当前的这个状态。换句话说,每一个状态都是过去历史的一个完整总结。这就是无后向性,又称为无后效性。

若是用前面的记号来描述无后向性,就是:对于肯定的xk,不管p1,k-1如何,最优子策略pkn*是惟一肯定的,这种性质称为无后向性。

[例3] Bitonic旅行路线问题

欧几里德货郎担问题是对平面给定的n个点肯定一条连结各点的、闭合的最短游历路线问题。图3(a)给出了七个点问题的解。Bitonic旅行路线问题是欧几里德货郎担问题的简化,这种旅行路线先从最左边开始,严格地由左至右到最右边的点,而后再严格地由右至左到出发点,求路程最短的路径长度。图3(b)给出了七个点问题的解。

图3

这两个问题看起来很类似。但实质上是不一样的。为了方便讨论,我将每一个顶点标记了号码。因为必然通过最右边的顶点7,因此一条路(P1-P2)能够看 成两条路(P1-7)与(P2-7)的结合。因此,这个问题的状态能够用两条道路结合的形式表示。咱们能够把这些状态中,两条路中起始顶点相同的状态归于 一个阶段,设为阶段[P1,P2]。

那么,对于Bitonic旅行路线问题来讲,阶段[P1,P2]若是能够由阶段[Q1,Q2]推出,则必须知足的条件就是:P1<Q1或 P2<Q2。例如,阶段[3,4]中的道路能够由阶段[3,5]中的道路加一条边4-5得出,而阶段[3,5]的状态却没法由阶段[3,4]中的状 态得出,由于Bitonic旅行路线要求必须严格地由左到右来旅行。因此若是咱们已经知道了阶段[3,4]中的状态,则阶段[3,5]中的状态必然已知。 所以咱们能够说,Bitonic问题知足无后向性,能够用动态规划来解决。

有些问题乍一看好像有后向性,但若是按照某种合理的方式从新划分阶段,就能够发现其本质上是无后向性的,因此关键是阶段的合理划分,这一点将在动态规划的技巧中详细阐述。

3.子问题的重叠性

在例1中咱们看到,动态规划将原来具备指数级复杂度的搜索算法改进成了具备多项式时间的算法。其中的关键在于解决冗余,这是动态规划算法的根本目的。动态规划实质上是一种以空间换时间的技术,它在实现的过程当中,不得不存储产生过程当中的各类状态,因此它的空间复杂度要大于其它的算法。以Bitonic旅行路线问题为例,这个问题也能够用搜索算法来解决。动态规划的时间复杂度为O(n2),搜索算法的时间复杂度为O(n!) ,但从空间复杂度来看,动态规划算法为O(n2),而搜索算法为O(n),搜索算法反而优于动态规划算法。选择动态规划算法是由于动态规划算法在空间上能够承受,而搜索算法在时间上却没法承受,因此咱们舍空间而取时间。

设原问题的规模为n,容易看出,当子问题树中的子问题总数是n的超多项式函数,而不一样的子问题数只是n的多项式函数时,动态规划法显得特别有意义,此时动态规划法具备线性时间复杂性。因此,可以用动态规划解决的问题还有一个显著特征:子问题的重叠性。这个性质并非动态规划适用的必要条件,可是若是该性质没法知足,动态规划算法同其余算法相比就不具有优点。

动态规划的基本思想

前文主要介绍了动态规划的一些理论依据,咱们将前文所说的具备明显的阶段划分和状态转移方程的动态规划称为标准动态规划, 这种标准动态规划是在研究多阶段决策问题时推导出来的,具备严格的数学形式,适合用于理论上的分析。在实际应用中,许多问题的阶段划分并不明显,这时若是 刻意地划分阶段法反而麻烦。通常来讲,只要该问题能够划分红规模更小的子问题,而且原问题的最优解中包含了子问题的最优解(即知足最优子化原理),则能够 考虑用动态规划解决。

动态规划的实质是分治思想和解决冗余,所以,动态规划是一种将问题实例分解为更小的、类似的子问题,并存储子问题的解而避免计算重复的子问题,以解决最优化问题的算法策略。

由此可知,动态规划法与分治法贪心法类 似,它们都是将问题实例概括为更小的、类似的子问题,并经过求解子问题产生一个全局最优解。其中贪心法的当前选择可能要依赖已经做出的全部选择,但不依赖 于有待于作出的选择和子问题。所以贪心法自顶向下,一步一步地做出贪心选择;而分治法中的各个子问题是独立的 (即不包含公共的子子问题),所以一旦递归地求出各子问题的解后,即可自下而上地将子问题的解合并成问题的解。但不足的是,若是当前选择可能要依赖子问题 的解时,则难以经过局部的贪心策略达到全局最优解;若是各子问题是不独立的,则分治法要作许多没必要要的工做,重复地解公共的子问题。

解决上述问题的办法是利用动态规划。该方法主要应用于最优化问题,这类问题会有多种可能的解,每一个解都有一个值,而动态规划找出其中最优(最大或最小)值的解。若存在若干个取最优值的解的话,它只取其中的一个。 在求解过程当中,该方法也是经过求解局部子问题的解达到全局最优解,但与分治法和贪心法不一样的是,动态规划容许这些子问题不独立,(亦即各子问题可包含公共 的子子问题)也容许其经过自身子问题的解做出选择,该方法对每个子问题只解一次,并将结果保存起来,避免每次碰到时都要重复计算。

所以,动态规划法所针对的问题有一个显著的特征,即它所对应的子问题树中的子问题呈现大量的重复。动态规划法的关键就在于,对于重复出现的子问题,只在第一次遇到时加以求解,并把答案保存起来,让之后再遇到时直接引用,没必要从新求解。

动态规划算法的基本步骤

设计一个标准的动态规划算法,一般可按如下几个步骤进行:

· 划分阶段:按照问题的时间或空间特征,把问题分为若干个阶段。注意这若干个阶段必定要是有序的或者是可排序的(即无后向性),不然问题就没法用动态规划求解。

· 选择状态:将问题发展到各个阶段时所处于的各类客观状况用不一样的状态表示出来。固然,状态的选择要知足无后效性。

· 肯定决策并写出状态转移方程:之因此把这两步放在一块儿,是由于决策和状态转移有着自然的联系,状态转移就是根据上一阶段的状态和决策来导出本阶段的状态。因此,若是咱们肯定了决策,状态转移方程也就写出来了。但事实上,咱们经常是反过来作,根据相邻两段的各状态之间的关系来肯定决策。

· 写出规划方程(包括边界条件):动态规划的基本方程是规划方程的通用形式化表达式。通常说来,只要阶段、状态、决策和状态转移肯定了,这一步仍是比较简单的。

动态规划的主要难点在于理论上的设计,一旦设计完成,实现部分就会很是简单。根据动态规划的基本方程能够直接递归计算最优值,可是通常将其改成递推计算,实现的大致上的框架以下:

标准动态规划的基本框架

1.  对fn+1(xn+1)初始化;    {边界条件}

2.  for k:=n downto 1 do 

3.      for 每个xk∈Xk do

4.        for 每个uk∈Uk(xk) do

            begin

5.            fk(xk):=一个极值;                 {∞或-∞}

6.            xk+1:=Tk(xk,uk);                  {状态转移方程}

7.            t:=φ(fk+1(xk+1),vk(xk,uk));       {基本方程(9)式}

8.            if  t比fk(xk)更优 then fk(xk):=t; {计算fk(xk)的最优值}

           end;  

9.  t:=一个极值;                               {∞或-∞}

10. for 每个x1∈X1 do

11.     if f1(x1)比t更优 then t:=f1(x1);       {按照10式求出最优指标}

12. 输出t;

可是,实际应用当中常常不显式地按照上面步骤设计动态规划,而是按如下几个步骤进行:

· 分析最优解的性质,并刻划其结构特征。

· 递归地定义最优值。

· 以自底向上的方式或自顶向下的记忆化方法(备忘录法)计算出最优值。

· 根据计算最优值时获得的信息,构造一个最优解。

步骤(1)--(3)是动态规划算法的基本步骤。在只须要求出最优值的情形,步骤(4)能够省略,若须要求出问题的一个最优解,则必须执行步骤 (4)。此时,在步骤(3)中计算最优值时,一般需记录更多的信息,以便在步骤(4)中,根据所记录的信息,快速地构造出一个最优解。

动态规划的实例分析

下面咱们将经过实例来分析动态规划的设计步骤和具体应用。例1已经在前文介绍过了。例1和例2是标准的动态规划,有明显的阶段和状态转移方程; 例三、例四、例五、例6是没有明显阶段划分的动态规划,也是通常常见的形式,其中对例四、例五、例6做了比较详细的分析;例7是比较特殊的动态规划,例8 是两重动态规划(即为了解决问题要进行两次动态规划)的例子。

· 例1 最短路径问题

· 例2 生产计划问题

· 例3 Bitonic旅行路线问题

· 例4 计算矩阵连乘积

· 例5 最长公共子序列

· 例6 凸多边形的最优三角剖分问题

· 例7 多边形计算

· 例8 字符识别

更多实例请参阅动态规划问题集

动态规划的技巧——阶段的划分和状态的表示

在动态规划的设计过程当中,阶段的划分和状态的表示是很是重要的两步,这两步会直接影响该问题的计算复杂性,有时候阶段划分或状态表示的不合理还会使得动态规划法不适用。

[例9] 街道问题

在下图中找出从左下角到右上角的最短路径,每步只能向右方或上方走。

这是一道简单而又典型的动态规划题,许多介绍动态规划的书与文章中都拿它来作例子。一般,书上的解答是这样的:

按照图中的虚线来划分阶段,即阶段变量k表示走过的步数,而状态变量xk表示当前处于这一阶段上的哪一点。这时的模型实际上已经转化成了一个特殊的多段图。用决策变量uk=0表示向右走,uk=1表示向上走,则状态转移方程以下:

(这里的row是地图竖直方向的行数)

咱们看到,这个状态转移方程须要根据k的取值分两种状况讨论,显得很是麻烦。相应的,把它代入规划方程而付诸实现时,算法也很繁。于是咱们在实现时,通常是不会这么作的,而代之如下面方法:

(这里Distance表示相邻两点间的边长)

这样作确实要比上面的方法简单多了,可是它已经破坏了动态规划的原本面目,而不存在明确的阶段特征了。若是说这种方法是以地图中的行(A、B、C、D)来划分阶段的话,那么它的"状态转移"就不全是在两个阶段之间进行的了。

也许这没什么大不了的,由于实践比理论更有说服力。可是,若是咱们把题目扩展一下:在地图中找出从左下角到右上角的两条路径,两条路径中的任何一条边都不能重叠,而且要求两条路径的总长度最短。这时,再用这种"简单"的方法就不太好办了。

若是非得套用这种方法的话,则最优指标函数就须要有四维的下标,而且难以处理两条路径"不能重叠"的问题。

而咱们回到原先"标准"的动态规划法,就会发现这个问题很好解决,只须要加一维状态变量就成了。即用xk=(ak,bk)分别表示两条路径走到阶段k时所处的位置,相应的,决策变量也增长一维,用uk=(xk,yk)分别表示两条路径的行走方向。状态转移时将两条路径分别考虑

在写规划方程时,只要对两条路径走到同一个点的状况稍微处理一下,减小可选的决策个数:

从这个例子能够看出,合理地划分阶段和选择状态能够给解题带来方便。

[例10] LITTLE SHOP OF FLOWERS (IOI’99)

PROBLEM

You want to arrange the window of your flower shop in a most pleasant way. You have Fbunches of flowers, each being of a different kind, and at least as many vases ordered in a row. The vases are glued onto the shelf and are numbered consecutively 1 through V, where V is the number of vases, from left to right so that the vase 1 is the leftmost, and the vase V is the rightmost vase. The bunches are moveable and are uniquely identified by integers between 1 and F. These id-numbers have a significance: They determine the required order of appearance of the flower bunches in the row of vases so that the bunch i must be in a vase to the left of the vase containing bunch j whenever i < j. Suppose, for example, you have a bunch of azaleas (id-number=1), a bunch of begonias (id-number=2) and a bunch of carnations (id-number=3). Now, all the bunches must be put into the vases keeping their id-numbers in order. The bunch of azaleas must be in a vase to the left of begonias, and the bunch of begonias must be in a vase to the left of carnations. If there are more vases than bunches of flowers then the excess will be left empty. A vase can hold only one bunch of flowers.

Each vase has a distinct characteristic (just like flowers do). Hence, putting a bunch of flowers in a vase results in a certain aesthetic value, expressed by an integer. The aesthetic values are presented in a table as shown below. Leaving a vase empty has an aesthetic value of 0.

 

V A S E S

1

2

3

4

5

Bunches

1 (azaleas)

7

23

-5

-24

16

2 (begonias)

5

21

-4

10

23

3 (carnations)

 -21 

5

-4

-20

20

According to the table, azaleas, for example, would look great in vase 2, but they would look awful in vase 4.

To achieve the most pleasant effect you have to maximize the sum of aesthetic values for the arrangement while keeping the required ordering of the flowers. If more than one arrangement has the maximal sum value, any one of them will be acceptable. You have to produce exactly one arrangement.

ASSUMPTIONS

· 1 <= F <= 100 where F is the number of the bunches of flowers. The bunches are numbered 1 through F.

· F<= V <= 100 where V is the number of vases.

· -50 <= Aij<= 50 where Aijis the aesthetic value obtained by putting the flower bunch i into the vase j.

INPUT

The input is a text file named flower.inp.

· The first line contains two numbers: F, V.

· The following F lines: Each of these lines contains V integers, so that Aij is given as the jth number on the (i+1)st line of the input file.

OUTPUT

The output must be a text file named flower.out consisting of two lines:

· The first line will contain the sum of aesthetic values for your arrangement.

· The second line must present the arrangement as a list of F numbers, so that the k’th number on this line identifies the vase in which the bunch k is put.

EXAMPLE

flower.inp:

3 5

7 23 -5 -24 16

5 21 -4 10 23

-21 5 -4 -20 20

flower.out:

53

2 4 5

EVALUATION

· Your program will be allowed to run 2 seconds.

· No partial credit can be obtained for a test case.

本题虽然是IOI’99中较为简单的一题,但其中大有文章可做。说它简单,是由于它有序,所以咱们一眼即可看出这题应该用动态规划来解决。可是,如何动态规划呢?如何划分阶段,又如何选择状态呢?

<方法1>

以花束的编号来划分阶段。在这里,第k阶段布置第k束花,共有F束花,有F+1个阶段,增长第F+1阶段是为了计算的方便;状态变量xk表示第k束花所在的花瓶。而对于每个状态xk,决策uk就是第k+1束花放置的花瓶号;最优指标函数fk(xk)表示从第k束花到第n束花所获得的最大美学值;A(i,j)是花束i插在花瓶j中的美学值,V是花瓶总数,F是花的总数。

状态转移方程为 

规划方程为

边界条件为:

,

事实上这是一个虚拟的边界。

最后要求的最大美学价值是

<方法2>

方法1的规划方程中的容许决策空间:xk+1≤uk≤V-(F-k)+1 比较麻烦,所以有待改进。仍是以花束的编号来划分阶段,第k阶段布置第k束花;状态变量xk表示第k束花所在的花瓶;注意,这里咱们考虑倒过来布置花瓶,即从第F束花开始布置到第1束花。因而状态变量uk表示第k-1束花所在的花瓶;最优指标fk(xk)表示从第一束花到第k束花所得到的美学价值;A(i,j)是花束i插在花瓶j中的美学值,V是花瓶总数,F是花的总数。则状态转移方程为:

规划方程为:

增长的虚拟边界条件为:

最后要求的最大美学价值是:

能够看出,这种方法实质上和方法1没有区别,可是容许决策空间的表示变得简单了。

<方法3>

以花瓶的数目来划分阶段,第k个阶段决定花瓶k中是否放花;状态变量xk表示前k个花瓶中放了多少花;而对于任意一个状态xk,决策就是第xk束花是否放在第k个花瓶中,用变量uk=1或0来表示。最优指标函数fk(xk)表示前k个花瓶中插了xk束花,所能取得的最大美学值。注意,这里仍然是倒过来考虑。

状态转移方程为

规划方程为

边界条件为

三种不一样的方法都成功地解决了问题,只不过由于阶段的划分不一样,状态的表示不一样,决策的选择有多有少,因此算法的时间复杂度也就不一样。

这个例子具备很大的广泛性。有不少的多阶段决策问题都有着不止一种的阶段划分方法,于是每每就有不止一种的规划方法。有时各类方法所产生的效果 是差很少的,但更多的时候,就像咱们的例子同样,两种方法会在某个方面有些区别。因此,在用动态规划解题的时候,能够多想想是否有其它的解法。对于不一样 的解法,要注意比较,好的算法好在哪里,差一点的算法差在哪里。从各类不一样算法的比较中,咱们能够更深入地领会动态规划的构思技巧。

动态规划实现中的问题

应用动态规划解决问题,在有了基本的思路以后,通常来讲,算法实现是比较好考虑的。但有时也会遇到一些问题,而使算法难以实现。动态规划思想设计的 算法从总体上来看基本都是按照得出的递推关系式进行递推,这种递推相对于计算机来讲,只要设计得当,效率每每是比较高的,这样在时间上溢出的可能性不大, 而相反地,动态规划须要很大的空间以存储中间产生的结果,这样可使包含同一个子问题的全部问题共用一个子问题解,从而体现动态规划的优越性,但这是以牺 牲空间为代价的,为了有效地访问已有结果,数据也不易压缩存储,于是空间矛盾是比较突出的。另外一方面,动态规划的高时效性每每要经过大的测试数据体现出来 (以与搜索做比较),于是,对于大规模的问题如何在基本不影响运行速度的条件下,解决空间溢出的问题,是动态规划解决问题时一个广泛会遇到的问题。

对于这个问题,能够考虑从如下一些方面去尝试:

一个思考方向是尽量少占用空间。如从结点的数据结构上考虑,仅仅存储必不可少的内容,以及数据存储范围上精打细算(按位存储、压缩存储等)。固然 这要因问题而异,进行分析。另外,在实现动态规划时,一个咱们常常采用的方法是用一个与结点数同样多的数组来存储每一步的决策,这对于倒推求得一种实现最 优解的方法是十分方便的,并且处理速度也有一些提升。可是在内存空间紧张的状况下,咱们就应该抓住问题的主要矛盾。省去这个存储决策的数组,而改为在从最 优解逐级倒推时,再计算一次,选择某个可能达到这个值的上一阶段的状态,直到推出结果为止。这样作,在程序编写上比上一种作法稍微多花一点时间,运行的时 效也可能会有一些(但每每很小)的降低,但却换来了不少的空间。于是这种思想在处理某些问题时,是颇有意义的。

但有时,即便采用这样的方法也会发现空间溢出的问题。这时就要分析,这些保留下来的数据是否有必要同时存在于内存之中。由于有不少问题,动态规划递 推在处理后面的内容时,前面比较远处的内容其实是用不着的。对于这类问题,在已经确信不会再被使用的数据上覆盖数据,从而使空间得以重复利用,若是能有 效地使用这一手段,对于至关大规模的问题,空间也不至于溢出(为了求出最优方案,保留每一步的决策还是必要的,这一样须要空间)。

通常地说,这种方法能够经过两种思路来实现:一种是递推结果仅使用Data1和Data2这样两个数组,每次将Data1做为上一阶段,推得 Data2数组,而后,将Data2经过复制覆盖到Data1之上,如此反复,便可推得最终结果。这种作法有一个局限性,就是对于递推与前面若干阶段相关 的问题,这种作法就比较麻烦;并且,每递推一级,就须要复制不少的内容,与前面多个阶段相关的问题影响更大。另一种实现方法是,对于一个可能与前N个阶 段相关的问题,创建数组Data[0..N],其中各项为最近N各阶段的保存数据。这样不采用这种内存节约方式时对于阶段k的访问只要对应成对数组 Data中下标为k mod (N+1)的单元的访问就能够了。这种处理方法对于程序修改的代码不多,速度几乎不受影响,并且须要保留不一样的阶段数也都能很容易实现。

当采用以上方法仍没法解决内存问题时,也能够采用对内存的动态申请来使绝大多数状况能有效出解。并且,使用动态内存还有一点好处,就是在重复使用内存而进行交换时,能够只对指针进行交换,而不复制数据,这在实践中也是十分有效的。

动态规划与其余算法的比较

动态规划与其说是一种算法,不如说是一种算法设计的策略,他的基本思想体现于许多其它算法之中。下面咱们经过比较动态规划和其余的一些算法之间的相互联系,来深刻理解动态规划的基本思想。

· 动态规划与静态规划——某些状况下能够相互转化

· 动态规划与递推——动态规划是最优化算法

· 动态规划与搜索——动态规划是高效率、高消费算法

· 态规划与网络流——动态规划是易设计易实现算法

动态规划的数学理论模型

在动态规划算法发展的初期,Bellman从纯粹的逻辑出发给出了最优性原理 --Principle of Optimality:

"An optimal policy has the property that whatever the initial state and initial decision are, then remaining decisions must constitute an optimal policy with regard to the state resulting from first decision."

他给出这个原理做为动态规划适用的条件,后来Morin在1982年证实了这只是一个充分条件而非必要条件。

动态规划开始只是应用于多阶段决策性问题,后来渐渐被发展为解决离散最优化问题的有效手段,进一步应用于一些连续性问题上。然而,动态规划更像是一 种思想而非算法,它没有固定的数学模型,没有固定的实现方法,其正确性也缺少严格的理论证实。所以,一直以来动态规划的数学理论模型是一个研究的热点。

目前比较流行的主要有两种理论模型:关系计算模型(relational calculus model)和估价网络模型(valuation network model)。

关于这两种流行理论,感兴趣的朋友能够参看如下论文:

其余资料

关于动态规划的应用,请参阅动态规划问题集

关于递归法,请参阅递归技术

关于分治法,请参阅分治法

关于动态规划的更多技巧和知识,请参阅如下资料:

· 如下是来自IOI国家集训队的论文: 

o 动态规划,方奇 (Zipped MS Word document)

o 把握本质,灵活运用——动态规划的深刻探讨,来煜坤 (Zipped MS Word document)

o 动态规划的深刻讨论,李刚 (Zipped MS Word document)

o 动态规划的特色及其应用,张辰 (Zipped MS Word document)推荐

· AXIOMS FOR DYNAMIC PROGRAMMING, Prakash P. Shenoy ,1996 (Zipped .pdf document)推荐

· Dynamic Programming: a different perspective, Sharon Curtis     , (Zipped .pdf document) 推荐

· How to Design Dynamic Programming Algorithms Sans Recursion, Kirk Pruhs (Zipped .ps document) 推荐

· Dynamic Programming via Static Incrementalization, Yanhong A. Liu, Scott D. Stoller (Zipped .ps document) 推荐

· Dynamic Programming in a Generalized Decision Mode, Ulrich Huckenbeck, December, 1993 (Zipped .ps document) 推荐

· Between Dynamic Programming and Greedy: Data Compression, Richard S. Bird , Oege de Moor, September 14 ,1995 (Zipped .pdf document)

· Using Local Trajectory Optimizers To Speed Up Global Optimization In Dynamic Programming, Christopher G. Atkeson , July 28,1995 (Zipped .ps document)

· A Fast Bit-Vector Algorithm for Approximate String Matching Based on Dynamic Programming, Gene Myers,March 27, 1998 (Zipped .ps document)

· Soft Dynamic Programming Algorithms: Convergence Proofs, Satinder P. Singh ,1993 (Zipped .ps document)

· Speeding up Dynamic Programming without Omitting any Optimal Solution and some Applications in Molecular Biology, Norbert Blum ,January 18, 2000 (Zipped .ps document)

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息