初识动态规划(dynamic programming)算法基本思想
目录
一、常见算法:
二、动态规划描述:
三、斐波那契数列
四、给定一个数组,求任意不相邻数字的最大值
五、解决动态规划问题的一般步骤
六、课后小练习
一、常见算法:
1、动态规划算法;2、分治法;3、贪心算法,一种对某些求最优解问题的更简单、更迅速的方法,4、回溯法,一种选优搜索法;5、分支限界法。
二、动态规划描述:
来自百度词条的介绍:是运筹学的一个分支,是求解决策过程最优化的过程。20世纪50年代初,美国数学家贝尔曼(R.Bellman)等人在研究多阶段决策过程的优化问题时,提出了著名的最优化原理,从而创立了动态规划。动态规划的应用极其广泛,包括工程技术、经济、工业生产、军事以及自动化控制等领域,并在背包问题、生产经营问题、资金管理问题、资源分配问题、最短路径问题和复杂系统可靠性问题等中取得了显著的效果 。
动态规划算法的基本思想:是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题就是初始问题的解。
动态规划适用情况:
1.最优子结构
最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。
2.无后效性
无后效性。即子问题的解一旦确定,就不再改变,不受在这之后、包含它的更大的问题的求解决策影响。
3.子问题重叠
子问题重叠性质。子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的效率。
三、斐波那契数列
fibonacci sequence :1,1,2,3,5,8,13,21,…… 求fib(n)
常规思路解法用递归时间复杂度为:O(2^N):
if (n == 1 || n == 2) {
return 1;
}else{
return fib(n - 1) + fib(n - 2);
}
当n变的很大时,查询速度会急剧下降,原因是在计算斐波那契的过程中出现了大量的子问题重叠过程,如下图所示
而通过非递归动态规划思想求解时间复杂度为:O(n)
int fibo(int n){
if(n < 1) return -1;
int F[n+1];
F[1] = 1;
F[2] = 1;
for(int i = 3; i <= n; i++){
F[i] = F[i-1] + F[i-2];
}
return F[n];
}
四、给定一个数组,求任意不相邻数字的最大值
例:比如给定数组:1,2,4,1,7,8,3
答案最大值为(1+4+7+3)15
递归形式:
def rec_opt(arr, n):
if n == 0:
return arr[0]
elif n == 1:
return max(arr[0], arr[1])
else:
A = rec_opt(arr, n - 2) + arr[n]
B = rec_opt(arr, n - 1)
return max(A, B)
print(rec_opt(arr,6))
而通过非递归动态规划思想求解:
def dp_opt(arr):
opt = np.zeros(len(arr))
opt[0] = arr[0]
opt[1] = max(arr[0],arr[1])
for i in range(2,len(arr)):
A = opt[i-2] + arr[i]
B = opt[i -1]
opt[i] = max(A,B)
return opt[len(arr)-1]
print(dp_opt(arr))
五、解决动态规划问题的一般步骤
动态规划所处理的问题是一个多阶段决策问题,一般由初始状态开始,通过对中间阶段决策的选择,达到结束状态。这些决策形成了一个决策序列,同时确定了完成整个过程的一条活动路线(通常是求最优的活动路线)。如图所示。动态规划的设计都有着一定的模式,一般要经历以下几个步骤。
初始状态→│决策1│→│决策2│→…→│决策n│→结束状态
(1)划分阶段:按照问题的时间或空间特征,把问题分为若干个阶段。在划分阶段时,注意划分后的阶段一定要是有序的或者是可排序的,否则问题就无法求解。
(2)确定状态和状态变量:将问题发展到各个阶段时所处于的各种客观情况用不同的状态表示出来。当然,状态的选择要满足无后效性。
(3)确定决策并写出状态转移方程:因为决策和状态转移有着天然的联系,状态转移就是根据上一阶段的状态和决策来导出本阶段的状态。所以如果确定了决策,状态转移方程也就可写出。但事实上常常是反过来做,根据相邻两个阶段的状态之间的关系来确定决策方法和状态转移方程。
(4)寻找边界条件:给出的状态转移方程是一个递推式,需要一个递推的终止条件或边界条件。
一般,只要解决问题的阶段、状态和状态转移决策确定了,就可以写出状态转移方程(包括边界条件)。
实际应用中可以按以下几个简化的步骤进行设计:
(1)分析最优解的性质,并刻画其结构特征。
(2)递归的定义最优解。
(3)以自底向上或自顶向下的记忆化方式(备忘录法)计算出最优值
(4)根据计算最优值时得到的信息,构造问题的最优解
六、课后小练习
背包问题,有一个背包,容量为4磅,现有如下物品
物品 重量 价格
吉他(G) 1 1500
音响(S) 4 3000
电脑(L) 3 2000
要求 讲物品装入背包,在不超出容量的情况下使背包的总价值最大
要求装入的物品不能重复