0-1背包

将n个项目的权重和值,放入一个容量为W的背包中,得到背包中最大的总价值。换句话说,给定两个整数数组val[0..n - 1]和wt [0 . .n-1],分别表示与n个项目相关的值和权重。同样,给定一个表示背包容量的整数W,找出val[]的最大值子集,使该子集的权值之和小于或等于W。

DP解决

动态规划

一个简单的解决方案是考虑项目的所有子集并计算所有子集的总权重和值。考虑唯一子集的总重量小于w .从所有这些子集,选择最大价值的子集。

1)最优子结构

要考虑所有项目的子集,每个项目可以有两种情况:

  1. 项目包含在最优子集中
  2. 不属于最优集。

因此,从n个项目中可以得到的最大值是以下两个值中的最大值。

  1. n-1项和W权值的最大值(不含第n项)。
  2. 第n项的值加上n-1项的最大值和W减去第n项(包括第n项)的权重。

如果第n项的权值大于W,则不能包含第n项,情况1是唯一的可能。

2)重叠子问题

下面是递归实现,它简单地遵循上面提到的递归结构。

/* 一个简单的递归实现0-1背包问题 */
#include<stdio.h> //返回两个整数最大值的实用函数
int max(int a, int b) { return (a > b)? a : b; } // 返回可放入容量为W的背包中的最大值
int knapSack(int W, int wt[], int val[], int n)
{ // 基本情况if (n == 0 || W == 0) return 0; // 如果第n项的重量大于背包容量W,则//这一项不能包含在最优解中   if (wt[n-1] > W) return knapSack(W, wt, val, n-1); //最多返回两种情况:  (1)包括第n项  (2)不包括在内else return max( val[n-1] + knapSack(W-wt[n-1], wt, val, n-1), knapSack(W, wt, val, n-1) );
} //驱动程序测试上述功能
int main()
{ int val[] = {60, 100, 120}; int wt[] = {10, 20, 30}; int  W = 50; int n = sizeof(val)/sizeof(val[0]); printf("%d", knapSack(W, wt, val, n)); return 0;
} 

输出:220

应该注意的是,上面的函数一次又一次地计算相同的子问题。看下面的递归树,K(1,1)被求了两次。这个简单递归解的时间复杂度为指数(2^n)。

在下面的递归树中,K()表示knapSack()。这两个下面递归树中的参数是n和W。递归树用于以下示例输入。

递归树背包容量2单位和3项1单位重量。

由于子问题是重新求值的,所以这个问题具有重叠子问题的性质。0-1背包问题具有动态规划问题的两个性质。与其他典型的动态规划(DP)问题一样,通过自底向上构造一个临时数组K[][],可以避免相同子问题的重计算。下面是基于动态规划的实现

int knapSack(int W, int wt[], int val[], int n)
{ int i, w; int K[n+1][W+1]; // 以自底向上的方式构建表K[][] for (i = 0; i <= n; i++) { for (w = 0; w <= W; w++) { if (i==0 || w==0) K[i][w] = 0; else if (wt[i-1] <= w) K[i][w] = max(val[i-1] + K[i-1][w-wt[i-1]],  K[i-1][w]); elseK[i][w] = K[i-1][w]; } } return K[n][W];
} 

(主函数与上面的一致)

时间复杂度:O(nW)其中n为物品数量,W为背包容量。

回溯法解决

回溯法

这个问题的解空间由 2^n 种不同的方法组成,它们为x分配0或1个值。因此,解空间与子集和问题的解空间相同。

需要使用边界函数来帮助杀死一些活动节点,而不需要实际展开它们。通过使用可通过扩展给定的活动节点及其任何后代获得的最佳可行解的值的上界来获得该问题的良好边界函数。如果这个上界不高于目前确定的最佳解的值,则可能会杀死活动节点。

这里我们使用固定的元组大小公式。如果在节点Z处已经确定了xi的值,1≤i≤k,则对k+1≤i≤n放宽xi = 0或1到0≤xi≤1的要求,用贪心法求解放宽问题,得到Z的上界。

程序  Bound(p、w、k、M)确定了在状态空间树的k+1级展开任何节点Z所能得到的最佳解的上界。

目标重量和收益是W(i)和P(i), 假定P (i) / W (i)≥P (i + 1) / W (i + 1), 1≤ i ≤ n。

procedure BOUND(p,w,k,M)
// p:当前利润总额
// w:当前的总重量
// k:最后删除项的索引
// M:背包大小
//结果是新的利润global  n , P(1:n) , W(1:n)
integer k, i l real b,c,p,w, Mb := p ;  c := wfor  i := k+1 to n do c := c + W(i)if c < M then b := b + P(j)else  return (b + (1 - (c - M)/W(i))*P(i))endifrepeatreturn (b)
end BOUND

备注:由此可知,节点Z的可行左子节点(x(k) = 1)的界与节点Z相同。因此,当回溯算法移动到节点的左子节点时,不需要使用边界函数。由于回溯算法会尝试在给定的左子节点和右子节点之间进行移动,所以只有在一系列成功的左子节点移动(i,e,移动到可行的左子节点)之后才需要使用边界函数。

伪代码:

procedure Knapsack(M,n,W,P, fw,fp,X)
// M:背包的大小
// n:权重和利润的数量
// W(1:n):权重
// P(1:n):对应利润;P (i) / W(i) ≥ P (i + 1) / W (i + 1)
// fw:背包的最终重量
// fp:最终的最大利润
// X(1:n),不是0就是1;如果W(k)不在背包里,则X(k) = 0,否则X(k) = 1integer n,k, Y(1:n), i , X(1:n) ;
real M, W(1:n), P(1:n), fw, fp, cw, cp ;
cw := cp := 0  ; k := 1 ; fp := -1
// cw =权重,cp =利润
loop
while  k <= n  and cw + W(k) <= M do
// 把k放在背包里
cw := cw + W(k) ; cp := cp + P(k) ; Y(k) := 1 ; k := k+1
repeat
if k > n then fp := cp; fw := cw ; k := n ; X := Y
// 更新解决方案
else  Y(k) := 0
// 超过M,所以对象k不合适
endif
while BOUND(cp,cw,k,M) ≤ fp do
// 在上面设置fp之后,BOUND = fpwhile k <>  0 and Y(k) <>  1 do k := k -1   // 找出背包里的最后一个权值repeatif k = 0 then return   endif    // 算法结束Y(k) := 0 ; cw := cw - W(k) ; cp := cp - P(k)  // 删除第k项repeat
k := k+1
repeat
end knapsack

分支限界法解决

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

三种算法对比

动态规划

动态规划通过最优子结构,将问题转换为子问题的求解。转换的过程中,涉及到某个具体的商品是否选择的问题。

回溯法

根据数学表达式,搜索解向量(x1, x2, ..., xn)的整个解空间
搜索的时候利用贪心性质(按照单位重量价值递减排序,估算可能的最高上界)、以及已经计算出的可行解作为界限进行剪枝
但是回溯法,原则上要穷尽所有可能,只不过是对有些分支提前返回了。

分支限界法

剪枝方法同回溯法是一样的:利用贪心性质(按照单位重量价值递减排序,估算可能的最高上界)、以及已经计算出的可行解作为界限进行剪枝。
唯一的不同是,分支限界法利用的是优先队列,并且,当针对一个结点进行扩展时,会将所有儿子结点进行展开,计算出所有儿子结点所能达到的最高上界。因此,当一个优先队列中首结点是一个可行解,则结束。

因此,可以看出回溯法与分支限界法的本质不同是在于搜索解空间的遍历方式不同
回溯法是深度优先,要穷尽解空间的所有可能,找到最优解。
分支限界法是广度优先,本质上也是穷尽了解空间的所有可能,找到最优解。

0-1背包问题详解(DP分支限界回溯三种方法)相关推荐

  1. 21天学习之二(Android 10.0 SystemUI默认去掉底部导航栏的三种方法)

    活动地址:CSDN21天学习挑战赛 1.概述 在定制化开发中,在SystemUI的一些定制功能中,针对默认去掉底部导航栏的方法有好几种,StatusBar和DisplayPolicy.java中api ...

  2. 详解梯度下降法的三种形式BGD、SGD以及MBGD

    在应用机器学习算法时,我们通常采用梯度下降法来对采用的算法进行训练.其实,常用的梯度下降法还具体包含有三种不同的形式,它们也各自有着不同的优缺点. 下面我们以线性回归算法来对三种梯度下降法进行比较. ...

  3. Cache超清晰逻辑详解(cache的三种映射)

    在说之前要向大家安利一个网站,http://www.ecs.umass.edu/ece/koren/architecture/Cache/tutorial.html,这是马萨诸塞大学安姆斯特分校的体系 ...

  4. Spring详解-------依赖注入的三种方式实例详解

    目录 1.什么是依赖注入 1.1类的关系 1.1.1 依赖关系(Dependency) 1.1.2 聚合(Aggregation) 1.2关系强度 2 为什么使用依赖注入 2.1开闭原则 2.1.1 ...

  5. 详解 Java 中的三种代理模式

    代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能. 这里使用 ...

  6. 详解跨平台APP的三种开发模式

    目前市面上主流的APP开发模式有三种:一种是Andriod和IOS的原生APP开发:一种是WebApp HTML5开发,最后一种是Hybrid App混合式开发. 1.Navtive APP开发(原生 ...

  7. Asp.net2.0动态加载用户控件的三种方法

    方法一: 直接拖放的用户控件 <!--这是某个aspx页--> ..... <%@ Register Src="TestControl.ascx" TagName ...

  8. 01背包问题详解(浅显易懂)

    01背包问题详解 01背包是一种动态规划问题.动态规划的核心就是状态转移方程,本文主要解释01背包状态转移方程的原理. 问题描述 01背包问题可描述为如下问题: 有一个容量为V的背包,还有n个物体.现 ...

  9. mysql_slow_详解MySQL中SlowLog的配置方法(图文)

    mysql 日志系统上线有段时间了,前端在慢慢切站点过来写入,未雨绸缪 diy了套 mysql 监控工具. 分为 slave  status ,sync,objec infot,userprivile ...

最新文章

  1. Could not initialize class org.apache.http.impl.conn.ManagedHttpClientConnectionFactory
  2. oracle 11g ORA-12514
  3. Linux远程软件xshell的使用
  4. 0X8009310B (ASN:276) win7安装证书时出现错误消息:找不到与此证书文件相关联的证书申请微软官方文档
  5. createinstance.java,weex android 0.17.0 createInstance fail
  6. 超越培训班同学的独门绝技
  7. python动物代码大全_python爬虫代码大全
  8. python pep8_Python 代码风格 和 PEP8
  9. 删除mysql临时文件_mysql自动备份数据库与自动删除临时文件
  10. Java工具类(获取当前主机操作系统名)
  11. go语言mongdb管道使用
  12. python按照日期筛选excel_用python判断Excel单元格格式为输出日期(日期字段位置不固定)的,按datetime格式输出日期(而非float)_python excle 日期列...
  13. vray铺装材质参数设计蓝海创意云渲染
  14. 利用selenium模拟登录webqq
  15. Java写一个矩阵输出并输出它的转置
  16. 【R语言】【1】初学R语言语法使用Rstudio编辑
  17. LintCode 661. 把二叉搜索树转化成更大的树
  18. 初识结构体之座机电话号码
  19. Visio2019安装教程(与正版office同时使用)
  20. Lytro Power Tool使用记录

热门文章

  1. 李航老师亲自推荐的《统计学习方法》课件下载
  2. 阿里巴巴提出Auto-Context R-CNN算法,刷出Faster RCNN目标检测新高度
  3. 荣耀20青春版能升鸿蒙吗,荣耀20青春版上手 配置跑分如何
  4. 思考问题:Python这两段等效代码内存占用为什么差别那么大?
  5. 零基础入门学习Python,我与python的第一次亲密接触后的感受
  6. 清华大学团队夺冠AAAI 2021国际深度元学习挑战赛
  7. 这17 种方法让 PyTorch 训练速度更快!
  8. 信息提示无法建立数据连接服务器,FileZilla 链接FTP服务器无法建立数据连接: ECONNREFUSED...
  9. 上海事职业培训软件测试高级,《软件测试人员(Java)(4级)》人力资源和社会保障部教材办公室、中国就业培训技术指导中心上海分中心、上海市职业培训研究发展中心 编_孔网...
  10. Spring data JPA方法命名规则