0/1背包问题——动态规划、回溯、分支限界法对比

2017.12.19 20:42:02 字数 3713 阅读 2820

目录

  • 1.问题描述
    1.1 问题描述
    1.2 问题的数学表示(规划类问题,此种表示可以转换为回溯法)
    1.3 三种方法的比较
  • 2.动态规划
    2.1 刻画一个最优解的结构特征(最优子结构)
    2.2 递归地定义最优解的值(重叠子问题)
    2.3 计算最优解的值,通常采用自底向上的方法
    2.4 利用计算出的信息构造一个最优解
  • 3.回溯法
    3.1 01背包问题的数学描述
    3.2 用回溯法搜索解空间
    3.3 一个示例
  • 4.分支限界法
    4.1 分支限界法解决0-1背包问题
    4.2 一个示例
  • 5.可以转换为0-1背包问题的双核问题
    5.1 题目描述
    5.2 转化为背包问题

1.问题描述

1.1 问题描述

假定n个商品重量分别为w0, w1, ..., wn-1,价值分别为p0, p1, ..., pn-1,背包载重量为M。怎样选择商品组合,使得价值最高?

1.2 问题的数学表示(规划类问题,此种表示可以转换为回溯法)

  • 假设xi表示商品i被装入背包的情况,xi = 0,1。根据题目要求,有如下约束方程和目标函数:

  • 问题归结为寻找一个满足上述约束方程并使目标函数达到最大的解向量X = (x1, x2, ..., xn)。

1.3 三种方法的比较

  • 动态规划通过最优子结构,将问题转换为子问题的求解。转换的过程中,涉及到某个具体的商品是否选择的问题。
  • 回溯法根据数学表达式,搜索解向量(x1, x2, ..., xn)的整个解空间
    搜索的时候利用贪心性质(按照单位重量价值递减排序,估算可能的最高上界)、以及已经计算出的可行解作为界限进行剪枝。
    但是回溯法,原则上要穷尽所有可能,只不过是对有些分支提前返回了。
  • 分支限界法
    剪枝方法同回溯法是一样的:利用贪心性质(按照单位重量价值递减排序,估算可能的最高上界)、以及已经计算出的可行解作为界限进行剪枝。
    唯一的不同是,分支限界法利用的是优先队列,并且,当针对一个结点进行扩展时,会将所有儿子结点进行展开,计算出所有儿子结点所能达到的最高上界。因此,当一个优先队列中首结点是一个可行解,则结束。
  • 因此,可以看出回溯法与分支限界法的本质不同是在于搜索解空间的遍历方式不同。
    回溯法是深度优先,要穷尽解空间的所有可能,找到最优解。
    分支限界法是广度优先,本质上也是穷尽了解空间的所有可能,找到最优解。

2.动态规划

2.1 刻画一个最优解的结构特征(最优子结构)

  • 假设01背包问题的一个最优解为S,其中i为序号最大的商品;
    那么S' = S - {i}必然是M - wi的最优解
    证明方法可以采用cut-paste方法进行证明

2.2 递归地定义最优解的值(重叠子问题)

  • 定义c[i, w]为商品1,....,i,最大重量为w的最优解(最大价值)。那么就有以下两种情况:
  • 如果wi > w,c[i, w]转化为求解一个子问题c[i-1, w];
  • 如果wi ≤ w,c[i, w]转换成了求解两个子问题:
    一个包含商品i,pi + c[i-1, w- wi];
    一个不包含商品i,c[i-1, w];
    两种情况中的较大者即为c[i, w]
  • (重叠子问题)很显然c[i-1, w-wi]与c[i-1, w]有重叠子问题。

2.3 计算最优解的值,通常采用自底向上的方法

  • 如下动态规划方法的运行时间为Θ(nM)

    动态规划计算方法

2.4 利用计算出的信息构造一个最优解

  • 如果c[i, w] = pi + c[i-1, w-wi],则i是答案的一部分;否则便不是。

3.回溯法

3.1 01背包问题的数学描述

  • 假设xi表示商品i被装入背包的情况,xi = 0,1。根据题目要求,有如下约束方程和目标函数:

  • 问题归结为寻找一个满足上述约束方程并使目标函数达到最大的解向量X = (x1, x2, ..., xn )。

3.2 用回溯法搜索解空间

3.2.1 解空间

  • 很显然,解空间为一棵高度为n的完全二叉树。所有解的可能性为所有的叶子节点,总共有2n种。

3.2.2 剪枝的方法(根据约束条件和bound来进行剪枝)

  • 上界bound = 0
  • 假定第i层左儿子表示商品i被装入背包,右儿子表示未被装入背包
  • 将物体按照价值重量比的非增顺序排序,然后按照这个顺序搜索,在搜索过程中,尽量沿着左儿子继续前进。
  • 当不能沿着左儿子继续前进时,得到问题的一个部分解,并把搜索转移到右子树。此时,估计由这个部分解所能得到的最大价值,把该值与当前的上界进行比较,如果高于上界,就继续在右子树上搜索,知道找到一个可行解,用可行解的值刷新上界bound。
  • 向上回溯,寻找其他可行解。如果部分解所估计的最大值小于当前的上界,就丢弃当前正在搜索的部分解,直接向上回溯。

最大值的估算法(跟分支限界法本质上是一样的)

  • 假定当前解是{x0, x1, ..., xk-1 }

向上回溯的方法

  • 如果当前的结点是左儿子分支结点,就转而搜索相应的右儿子分支结点;
  • 如果当前的结点是右儿子分支结点,就沿着右儿子分支结点向上回溯,知道左儿子分支结点为止,然后再转而搜索相应的右儿子分支结点

3.2.3 回溯法的步骤描述

w_cur——表示当前正在搜索的部分解中转入的总重量
p_cur——当前总价值
p_est——部分解可能达到的最大价值的估计值
p_total——当前搜索到的所有可行解中的最大价值,是当前目标函数的上界
yk、xk——部分解的第k个分量及其副本
k——表示当前搜索深度

  • step1.按商品价值重量比的非增排序排序
  • step2.w_cur、p_cur和p_total初始化为0,把部分解初始化为空,k=0
  • step3.从当前的部分解可取得的最大价值p_est
  • step4.若p_est > p_total,转step5;否则,转step8
  • step5.从vk开始把商品装入背包,直到没有商品可装货装不下vi为止,并生成部分解yk, ..., yi,k ≤ i < n,刷新p_cur
  • step6.如果i ≥ n,得到一个新的可行解,把所有的yi复制给xi,p_total = p_cur,p_total是目标函数的新界;令k = n,转step3,以便回溯搜索其他的可能解
  • step7.否则,得到一个部分解,令k=i+1,舍弃商品vi,从商品vi+1继续装入,转step3.
  • 回溯)step8.当i ≥ 0且yi为0时,执行i = i -1,直到yi ≠ 0为止;即沿右儿子分支结点方向回溯,直到左儿子分支结点。
  • step9.如果i < 0,算法结束,否则,转step10
  • step10.令yi = 0,w_cur = w_cur - wi, p_cur = p_cur - pi, k = i + 1,转step3;从左儿子分支结点转移到相应的右儿子分支结点,继续搜索其他的部分解或可能解。

3.3 一个示例

M = 50
商品重量分别为5,15,25,27,30
商品价值分别为12,30,44,46,50
上面已经按照单位重量价值递减顺序排列。

4.分支限界法

4.1 分支限界法解决0-1背包问题

  • 按价值重量比 递减 的顺序,对n个商品进行排序
    排序后商品序号的结合为S = {0, 1, ..., n-1}
  • 将这些商品分为3个集合:
    S1——选择装入背包的商品集合
    S2——不选择装入背包的商品集合
    S3——尚待选择的商品集合
  • S1(k)、S2(k)、S3(k)分别表示在搜索深度为k时的3个集合中的商品。开始时有:
    S1(0) = ∅
    S2(0) = ∅
    S3(0) = {0, 1, ..., n-1}

4.1.1 分支方法(二叉分支)

  • 假设比值pi/wi最大的商品序号为s(s ∈ S3),用s进行分支,一个分支结点表示把商品s装入背包,另一个分支结点表示不把商品s装入背包。
    当商品按照价值重量比递减排序后,s就是集合S3(k)中的第一个元素。特别地,当搜索深度为k时,商品s的序号就是集合S中的元素k。
  • 把商品s装入背包的分支结点
    S1(k+1) = S1(k) ∪ {k}
    S2(k+1) = S2(k)
    S3(k+1) = S3(k) - {k}
  • 不把商品s装入背包的分支结点
    S1(k+1) = S1(k)
    S2(k+1) = S2(k) ∪ {k}
    S3(k+1) = S3(k) - {k}

4.1.2 上界估算方法(按照单位价值最大进行贪心选择)

  • 假定b(k)表示在搜索深度为k时,某个分支结点的背包中商品的价值上界。
    此时S3(k) = {k, k+1, ..., n-1}。用如下方法计算两种分支结点背包中商品价值的上界:

  • 上述公式的理解
    1)按照一个商品是否加入到S1集合,总共有2n个叶子节点,每个叶子节点对应一种情况
    2)当一层一层向下搜索是,如果当前S1集合中的总重量超过了载重量M,则直接将b(k)置为0,该分支终止。
    为什么这样做?因为在搜索上一层时,该商品不应该加入到S1集合,这种不加入该商品情况对应于另一个分支。加入该商品的此分支已经不满足要求了,所以剪枝。

4.1.3 分支限界法求解步骤

每个结点都包含如下信息:
  S1——当前选择装入背包的商品集合
  S2——当前不选择装入背包的商品集合
  S3——当前尚待选择的商品集合
  k——搜索深度
  b——上界
bound——一个可行解的取值,当做剪枝的标准

  • step1.bound = 0,把商品按价值重量比递减排序
  • step2.建立根节点X
    X.b = 0
    X.k = 0
    X.S1 = ∅
    X.S2 = ∅
    X.S3 = S
  • step3. 若X.k == n,算法结束,X.S1即为装入背包中的物体,X.b即为装入背包中物体的最大价值;
    否则转向step4
  • 分支1)step4.建立结点Y
    Y.S1 = X.S1 ∪ {X.k}
    Y.S2 = X.S2
    Y.S3 = X.S3 - {X.k}
    Y.k = X.k + 1
    计算Y.b,将Y.b与bound进行比较,据此判定是否插入优先队列;当S3为空时,找到一个可行解,判定是否更新bound。
  • 分支2)step5.建立结点Z
    Z.S1 = X.S1
    Z.S2 = X.S2 ∪ {X.k}
    Z.S3 = X.S3 - {X.k}
    Z.k = Z.k + 1
    计算Z.b,将Z.b与bound进行比较,据此判定是否插入优先队列;当S3为空时,找到一个可行解,判定是否更新bound。
  • step6.取出优先队列首元素作为结点X,转向step3

4.2 一个示例

  • 有5个商品,重量分别为8,16,21,17,12,价值分别为8,14,16,11,7,背包的载重量为37,求装入背包的商品及其价值。

5.可以转换为0-1背包问题的双核问题

5.1 题目描述

一种双核CPU的两个核能够同时的处理任务,现在有n个已知数据量的任务需要交给CPU处理,假设已知CPU的每个核1秒可以处理1kb,每个核同时只能处理一项任务。n个任务可以按照任意顺序放入CPU进行处理,现在需要设计一个方案让CPU处理完这批任务所需的时间最少,求这个最小的时间

输入描述:

输入包括两行: 第一行为整数n(1 ≤ n ≤ 50) 第二行为n个整数length[i](1024 ≤ length[i] ≤4194304),表示每个任务的长度为length[i]kb,每个数均为1024的倍数。

输出描述:

输出一个整数,表示最少需要处理的时间

输入例子:

5 3072 3072 7168 3072 1024

输出例子:

9216

5.2 转化为背包问题

  • 最小时间的意思即两个核同时满负荷运行,并且当两个核所处理的任务量都接近于总任务量M的一半时,时间最少
  • 因此题目转换为:对于其中一个核,假设其任务量为上限M/2,在所有这些任务中选择一个处理组合,使得这些任务组合在不超过M/2的情况下达到最大
  • 因此本质上就是一个背包问题,背包的容量为M/2,商品的单位重量价值均为1,商品的重量即为任务所需要的时间量。

http://www.taodudu.cc/news/show-6879950.html

相关文章:

  • Leetcode回溯算法经典题目总结
  • 回溯法实例详解(转)
  • N皇后问题(递归回溯)
  • 通信理论知识回溯
  • 《数据结构、算法与应用 —— C++语言描述》学习笔记 — 回溯法
  • 回溯统计史
  • 代码随想录刷题记录:回溯算法篇
  • 回溯算法:0-1背包问题
  • 常用十大算法_回溯算法
  • C语言算法之回溯法
  • 专题练习——回溯
  • java中对递归的限制是什么_什么是递归,通过这篇文章,让你彻底搞懂递归
  • NFA
  • DFA与NFA的比较
  • NFA的实现
  • NFA构造及NFA转化为DFA
  • 从正则表达式到NFA
  • NFA/DFA
  • NFA算法
  • 【2023/05/19】NFA
  • 承德避暑山庄-邯郸,开辟旅游路线新华创
  • 信封错排问题
  • CSS信封
  • 两个信封之谜
  • 信封大小
  • 信封模式,图片放进一个固定的信封里面:图像预处理
  • 信封问题
  • 图片的展开与收起
  • 数字信封详解
  • 开信封效果

0/1背包问题——动态规划、回溯、分支限界法对比相关推荐

  1. 0/1背包问题——动态规划方法

    1.定义 动态规划:把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解. 2.求解步骤 (1)找到状态转化条件 (2)归纳状态转移方程 (3)定义初始条件值 3.实例解析--0/1背包 ...

  2. 0/1背包问题-----动态规划求解

    问题描述 有n个物品和一个容量为c的背包,从n个物品中选取装包的物品.物品i的重量为w[i],价值为p[i].一个可行的背包装载是指,装包的物品总重量不超过背包的重量.一个最佳背包装载是指,物品总价值 ...

  3. 算法之动态规划,问题三:0 1 背包问题

    目录 1 问题的描述 2 贪心算法? 3 算法的参数约定及递推式 4 算法具体实现 5 回溯原问题的解 6 案例输出 7 源代码 1 问题的描述 0 1 背包的问题: 有n个物品(权重Wi>0, ...

  4. 0/1背包问题-----回溯法求解

    问题描述 有n个物品和一个容量为c的背包,从n个物品中选取装包的物品.物品i的重量为w[i],价值为p[i].一个可行的背包装载是指,装包的物品总重量不超过背包的重量.一个最佳背包装载是指,物品总价值 ...

  5. 【动态规划】0/1背包问题

    问题 H: [动态规划]0/1背包问题 时间限制: 1 Sec  内存限制: 64 MB 提交: 152  解决: 95 [提交] [状态] [讨论版] [命题人:admin] 题目描述 张琪曼和李旭 ...

  6. 回溯法 —— 求解0/1背包问题(剪枝)

    0/1背包问题 题目描述: 有n个重量分别为w1,w2,-,wn的物品(物品编号为1~n),它们的价值分别为v1,v2,-,vn,给定一个容量为W的背包.设计从这些物品中选取一部分物品放入该背包的方案 ...

  7. 动态规划——0/1背包问题(全网最细+图文解析)

    ✨动态规划--0/1背包问题(全网最细+图文解析) 作者介绍:

  8. 动态规划之0/1背包问题(动态规划入门)

    动态规划很早以前就接触过但是因为太晦涩难懂一下子到现在才开始真正的学习到其中的道理,0/1背包问题是动态规划的入门类问题 比较好理解 首先我们要知道动态规划是用于解决最优解的问题 它是一种思想而不是一 ...

  9. 令人头疼的背包九讲(1)0/1背包问题

    点击上方"Jerry的算法和NLP",选择"星标"公众号       重磅干货,第一时间送达 背包问题是一个经典的动态规划模型.它既简单形象容易理解,又在某种程 ...

最新文章

  1. html xhtml and css,HTML与XHTML的重要区别
  2. Nat. Med. | 人工智能临床研究新指南
  3. oracle 不存在函数,Oracle – 此范围内不存在名称为X的函数
  4. js能否打印服务器端文档,js打印远程服务器文件
  5. java applet 事件_applet中的普通事件被按钮事件劫走!!!!!在线等。。。。。...
  6. LeetCode() Search in Rotated Sorted Array
  7. 自定义MySQL实用的函数和存储过程(持续更新)
  8. java面试宝典-抱你过岸
  9. 《学习geometric deep learning笔记系列》第一篇,Non-Euclidean Structure Data之我见
  10. 小程序--获取手机型号
  11. Ubuntu命令行播放声音
  12. unity5.3 场景烘焙
  13. “经历了人生百态世间的冷暖,这笑容温暖纯真”
  14. 跨域解决方式——JSONP,CORS
  15. wifi共享精灵 强大的网络伴侣
  16. 利用字符数组c语言编写迷宫探路游戏,C语言打造——迷宫游戏
  17. 站立会议_充分利用日常站立会议的两种方法
  18. 从现网PON口带宽利用率看XGS-PON的适用场景
  19. Moss量化模型部署记录
  20. mysql 安装 知乎_知乎问答3-MySQL安装详解

热门文章

  1. ES5数组去重(面试考题、面试基础、必掌握)
  2. 【Python】三个步骤,写一个电脑监控程序
  3. C++面试宝典带你走上Offer收割机之路
  4. python学习笔记29(利用pycharm在windows下出现闪退以及turtle 入门)
  5. 命名规范与注释规范概述
  6. java判断空对象为空_Java判断对象是否为空(包括null ,)的方法
  7. 系统学习大模型的20篇论文
  8. Web前端学习笔记08:HTML5_CSS3
  9. MySQL存储引擎介绍及区别
  10. nodejs与php混合,node.js - php与nodejs的加密数据互通