从0-1背包问题到动态规划
算法——贪心算法解0-1背包问题
局部最优策略(locally optimal decisions,比如贪心算法),并不保证全局最优(global optimums)
“在我的后园,可以看见墙外有两株树,一株是枣树,还有一株也是枣树。”,同样如果有两个手表,为了达到0/1背包问题的要求,也可转化为一个手表,还有一个手表。
brute force(暴力法)的本质是 exhaustive enumeration(穷举法)
一个算法的时间复杂度为指数级时,将会产生十分恐怖的计算量,而动态规划算法可以用来解决指数级时间复杂度的问题,只是说,有些指数级时间复杂度的问题可以通过动态规划算法求解,并非全部。
动态规划(Dynamic programming)核心概念有二:
overlapping subproblems: 重叠子问题
或者说,子问题(subproblems)出现了重叠,子问题的“重叠”意味着计算机的“重复计算”。比如,斐波那契数列的例子不像二分搜索(子问题之间比如独立,也即不存在子问题重叠的问题),可参考 每周一刷——从斐波那契数列到动态规划 。
optimal substructure: 最优子结构
所谓动态规划即是寻找这样的一个最优子结构(substructure),它通过引入 memo 查找表(look-up table)的形式实现对重叠的子问题只进行有限次的计算。也即:record value 1st time,look it up the subsequent times we need it(一次记录,多次使用)
背包问题(knapsack problem)又叫装箱问题(bin packing)。所谓0-1背包问题,对于一件物品要么拿走,要么不拿,不存在拿部分的情况,自然可与二进制对应起来,所谓当物品为 nn 时,样本空间的大小为:2n2^n。
为了实现用动态规划的方法进行背包问题的求解,我们首先来看使用动态规划求解斐波那契数列的问题,关于用动态规划求解斐波那契数列的详细讨论请见 每周一刷——从斐波那契数列到动态规划 。
def fib(n, m):if n not in m:m[n] = fib(n-1, m) + fib(n-2, m)return m[n]if __name__ == '__main__':m = {0:0, 1:1}print([fib(n, m) for n in range(10)])# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
decision tree(决策树)
- weights = [5, 3, 2],三个物品各自的重量;
- values = [9, 7, 8],三个物品各自的价值;
- max = 5,背包的最大承重;
所谓0/1背包问题,也即对每一件物品只有选和不选两种选择,也即分二叉,从当前节点出发,有两个分支。
我们定义如下的树的节点(node)结构:物品的编号
,背包还能容纳的最大重量
,当前背包所放物品的价值
构成的三元组,我们以逆序遍历每件物品,所以根节点结构为:[2, 5, 0]。
def maxVal(i, w, v, c):if i == 0:return v[i] if w[i] <= 0 else 0without_i = maxVal(i-1, w, v, c)if w[i] > c:return without_iwith_i = v[i] + maxVal(i-1, w, v, c-w[i])return max(without_i, with_i)if __name__ == '__main__':weights = [5, 3, 2]values = [9, 7, 8]n, c = len(weights), 5print(maxVal(n-1, weights, values, c))
上例中的重叠子问题(overlapping subproblem)还不明显,当物品较多时,画出其决定树,便会出现大量的重叠子问题,又因为weights
和values
是固定不变的,真正变化的是物品编号以及当前背包还能容纳的物品重量。
def fastMaxVal(i, w, v, c, m):try:return m[(i, c)]except KeyError:if i == 0:if w[i] <= c:m[(i, c)] = v[i]return m[(i, c)]m[(i, c)] = 0return 0without_i = fastMaxVal(i-1, w, v, c, m)if w[i] > c:m[(i, c)] = without_ireturn m[(i, c)]with_i = v[i] + fastMaxVal(i-1, w, v, c-w[i], m)m[(i, c)] = max(with_i, without_i)return m[(i, c)]
if __name__ == '__main__':ws = [5, 3, 2]vs = [9, 7, 8]n, c = len(ws), 5m = {}print(fastMaxVal(n-1, ws, vs, c, m))
从0-1背包问题到动态规划相关推荐
- 动态规划之0/1背包问题(动态规划入门)
动态规划很早以前就接触过但是因为太晦涩难懂一下子到现在才开始真正的学习到其中的道理,0/1背包问题是动态规划的入门类问题 比较好理解 首先我们要知道动态规划是用于解决最优解的问题 它是一种思想而不是一 ...
- 【算法设计与分析】7、0/1背包问题,动态规划
/** * 书本:<算法分析与设计> * 功能:给定n种物品和一个背包,物品i的重量是Wi, 其价值为Vi,问如何选择装入背包的物品,使得装入背包的物品的总价值最大? * 文件:beiBa ...
- 0/1背包问题——动态规划方法
1.定义 动态规划:把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解. 2.求解步骤 (1)找到状态转化条件 (2)归纳状态转移方程 (3)定义初始条件值 3.实例解析--0/1背包 ...
- 【动态规划】0/1背包问题
问题 H: [动态规划]0/1背包问题 时间限制: 1 Sec 内存限制: 64 MB 提交: 152 解决: 95 [提交] [状态] [讨论版] [命题人:admin] 题目描述 张琪曼和李旭 ...
- 动态规划——0/1背包问题(全网最细+图文解析)
✨动态规划--0/1背包问题(全网最细+图文解析) 作者介绍:
- 0/1背包问题——动态规划、回溯、分支限界法对比
0/1背包问题--动态规划.回溯.分支限界法对比 2017.12.19 20:42:02 字数 3713 阅读 2820 目录 1.问题描述 1.1 问题描述 1.2 问题的数学表示(规划类问题,此种 ...
- 0/1背包问题-----动态规划求解
问题描述 有n个物品和一个容量为c的背包,从n个物品中选取装包的物品.物品i的重量为w[i],价值为p[i].一个可行的背包装载是指,装包的物品总重量不超过背包的重量.一个最佳背包装载是指,物品总价值 ...
- 【Python】0/1背包、动态规划
0/1背包问题:在能承受一定重量的背包中,放入重量不同,价值不同的几件物品,怎样放能让背包中物品的价值最大? 比如,有三件物品重量w,价值v分别是 w=[5,3,2] v=[9,7,8] 包的容量是5 ...
- Python 0/1背包、动态规划
参考:http://www.cnblogs.com/fcyworld/p/6243012.html Python 0/1背包.动态规划 0/1背包问题:在能承受一定重量的背包中,放入重量不同,价值不同 ...
最新文章
- linux 编译sqlitecpp,编译安装sqlite3数据库
- 每日一皮:鼓励师招到了,原来是这样的...
- Oracle中的两种验证方式:操作系统验证和密码文件验证,通过操作系统验证的方式解决客户端登录不了数据的问题
- php 集合安装,centos7安装php5.6报错集合
- 列表,字典表达式以及三元表达式
- oracle自定义存储过程:删除表(无论表是否存在)和检测表是否存在
- 人工智能产业链深度透析-技术层
- 【简短】Autodesk宣布支持Windows 7
- Ubuntu中ssh远程报错:packet_write_wait: Connection to 192.168.163.190 port 22: Broken pipe lost connection
- 2016年北京大学信息学奥赛训练营上机考核第四场【pkusc真题模拟总结】
- 公司危机、下岗困局、不受重视,程序员该如何面对职场挫折?
- 工作文档化升级为工作列表化
- python手写输入法开发_QT 手写输入法 - 程序员狗蛋的个人空间 - OSCHINA - 中文开源技术交流社区...
- MATLAB中的数组
- 2022-5-20 解决 cdn.jsdelivr 打不开
- 区块链技术及应用发展概述
- WAVEFORMATEX 格式说明
- 【Lua编程基础】Lua编程SciTe和SublimeI的配置和使用
- 某些在线点播视频的地址格式
- :first-child和:first-of-type的区别
热门文章
- 使用oracle创建表问题
- mysql 参数 列 排序_将参数放入MySQL IN()后,按降序对列进行排序?
- docker gpu 创建 训练环境_巧用 Docker 快速部署 GPU 环境
- LeetCode 5.最长回文子串(动态规划)
- 机器学习Scikit-Learn模块详解
- Redis教程:数据对象分析(一)
- 图像处理基础(三)_像素之间的3种关系
- python中logging模块的一些简单用法
- 改变图像的对比度和亮度
- <FlyoutItem FlyoutDisplayOptions=“AsMultipleItems“ >