动态规划

来源:互联网 发布:4g网络优化工程师分期 编辑:程序博客网 时间:2024/06/03 14:55

一、基本概念
动态规划是运筹学的一个分支,是求解决策过程最优化的数学方法(Dynamic Programming)动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,称之为动态规划(多阶段最优化决策问题)
二、基本思想与策略
与分治法类似,将问题分解成若干子问题,按顺序求解子问题,前一子问题的解为后一子问题提供了有用的信息。在求解任一子问题时,列出可能的局部解,通过决策保留那些有可能达到的最优的局部解,丢弃其他的局部解。以此解决各子问题,最后一个子问题就是初始问题的解。
动态规划多有重叠子问题,为减少重复计算,对每个子问题只求解一次,将不同阶段的不同状态保存在一个二维数组中。
与分治法的不同:动态规划子问题不是独立的,前一子问题的解释求解下一子问题的基础
三、适用的情况
能采用DP求解一般具有三个性质:
(1)最优化原理:如果最优解所包含的的子问题的解也是最优的,就称该问题具有最优子结构,满足最优化原理;
(2)无后效性:某阶段状态一旦确立,就不受这个状态以后决策的影响。也就是说,某状态以后的过程不会影响到以前的状态,只与当前状态有关。
(3)有重叠子问题:即子问题之间是不独立的,一个子问题在下阶段决策中可能被多次用到。
四、求解基本步骤
(1)划分阶段:按照问题的时间或者空间顺序划分,把问题划分成几个阶段,注意,划分后的阶段一定是有序或者可排序的,否则问题无法求解
(2)确定状态和状态变量:将问题发展到各个阶段时所处的各种客观情况用不同的状态表示出来,要满足无后效性;
(3)确定决策并写出状态转移方程:状态转移就是根据上一阶段的状态和决策导出本阶段的状态。
(4)寻找边界条件:给出的状态转移方程是一个递推式,需要他的终止条件
实际应用中简化:
(1)分析最优解的性质,并刻画其结构特征;
(2)递归的定义最优解
(3)自底向上或自顶向下的记忆化计算出最优值
(4)根据计算最优值时得到的信息,构造问题的最优解
五、算法的实现说明
确定动态规划的三要素:
(1)问题的阶段
(2)每个阶段的状态
(3)从前一个阶段转化到后一个状态之间的递推关系,递推关系必须是从次小的问题开始到较大的问题之间的转化
求解过程可以使用最优决策表来描述:一个二维表,行代表决策的阶段,列代表问题状态,表格需要填写的数据对于此问题在某一阶段某个状态下的最优值(如最短路径,最大公共子序列,最大价值等)
经典例题:
1.题目描述
给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数。
当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案。
输入描述:
输入为两行:
第一行为两个正整数n(1 ≤ n ≤ 1000),sum(1 ≤ sum ≤ 1000)
第二行为n个正整数Ai,以空格隔开。
输出描述:
输出所求的方案数
示例1
输入
5 15
5 5 10 2 3
输出
4

if __name__=="__main__":    n,Sum=map(int,raw_input().split())    A=map(int,raw_input().split())    ###method 1    count=[[1]+[0]*Sum for i in range(n+1)]#    for i in range(n):        for j in range(Sum+1):            count[i+1][j]=count[i][j]            if j>=A[i]:                count[i+1][j]+=count[i][j-A[i]]    print count[n][Sum]

注:当取i时,实际上操作的是第i个元素(不是第i-1个,即第一行跳过),首先赋值,加入第i个元素时,初始值是加入第i-1个元素的方案数,接下来只要计算取i个元素的方案数。
当j>=A[i]时,即A[i]可以加,固定这种方案中必须要有A[i],我们要求的则是和为j-A[i]的方案数,