动态规划算法:
动态规划算法介绍:
- 动态规划算法的核心思想是:将大问题划分为小问题进行解决,从而一步步获得最优解的处理算法。
- 动态规划算法的基本思想是:将待求解的问题分解成若干子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
- 适合用于动态规划的求解的问题,经分解得到子问题往往不是互相独立的。(即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解)
- 动态规划可以通过填表的方式来逐步推进,得到最优解。
动态规划算法最佳实践:背包问题
有一个背包
,容量为4磅,现有如下物品 :
物品 | 重量 | 价格 |
---|---|---|
吉他(G) | 1 | 1500 |
音响(S) | 4 | 3000 |
电脑(L) | 3 | 2000 |
- 要求达到的目标为装入背包的总价值最大,并且重量不超出。
- 要求装入的物品不能重复。
思路分析:
-
背包问题主要是指一个给定容量的背包、若干具有一定价值和贵重的物品,如何选择物品放入背包使价格最大,其中又分为01背包和完全背包(完全背包指的是:每种物品都有无限件可用)。
-
这里的问题属于01背包,即每个物品最多放一个,而无限背包可以转化为01背包。
-
算法的主要思想,利用动态规划来解决,每次遍历到的第i个物品,根据 w[i] 和 v[i] 来确定是否需要将物品放入背包。即对于 给定的n个物品,设va[i],w[i] 分别为第i个物品的价值和重量,c为背包的含量。再令
v[i][j](二维数组,用于表示下表,行表示价值,列表示容量)
表示在前i个物品中能够**装入容量为j **(j 为给顶的背包容量,因为需要不断的测试是否达到最大容量,所有设置容量是一个变量j ) 的背包中的最大价值,则有以下结果。两个箭头分别代表v 的 i 和 j (行和列)
-
v[i][0] = v[0][j] = 0
表示第一行和第一列为0,如上图。(由于数组下标索引由0开始,这里方便用 i 和 j 代表具体的哪一个) -
当w[i] > j 时 说明背包容量不足以放下第i件物品,只能选择不拿,此时,
v[i][j] = v[i-1][j] ;
即当准备加入新增的商品的重量大于当前背包的 容量时,就使用上一个单元格的装入策略(如上图,音响为4磅,当j = 1,2,3时 装入策略为吉他的价格。
-
当 j >= w[i]时(重量有空余 )这是背包容量可以放下第i件物品,可以选择拿还是不拿,判断标准:拿这件物品是否能获取更大的价值。
v[i][j] = max{v[i-1][j],va[i]+v[i-1][j-w[i]]}
当准备加入的新增商品的容量小于等于当前背包的容量,判断上一策略跟现有策略哪个大。其中va[i] 表示的是商品的价格。
其中:
v[i-1][j] : 就是上一个单元格装入的最大值
va[i] : 表示当前商品的价值。 j-w[i] 表示剩余的重量
v[i-1] [j-w[i]]: 装入 i-1商品到剩余空间 j-w[i]的最大值 剩余空间对于其他商品种类的最大价值
验证公式,如上图
v[3][4] = 2000 + 1500 即i = 3 j = 4
【j = 4 】 >【 w[3] = 3(磅)】
v[3][4] = max { v[2][4],va[3]+v[2][1] } = {3000,2000 + 1500}