背景

  • 0-1背包是非常经典的算法问题,很多场景都可以抽象成这个问题模型。这个问题的经典解法是动态规划。
  • 不过还有一种简单但没有那么高效的解法,这里用的回溯算法。
  • 0-1背包问题有很多变体,我这里介绍一种比较基础的。我们有一个背包,背包总的承载重量是Wkg。现在我们有n个物品,每个物品的重量不等,并且不可分割。 我们现在期望选择几件物品,装载到背包中。在不超过背包所能装载重量的前提下,如何让背包中物品的总重量最大?
  • 实际上,假设物品是不可分割的,要么装要么不装,所以叫0-1背包问题。显然,这个问题已经无法通过贪心算法来解决了。我们现在来看看,用回溯算法如何来解决。
  • 对于每个物品来说,都有两种选择,装进背包或者不装进背包。对于n个物品来说,总的装法就有2^n种,去掉总重量超过Wkg的,从剩下的装法中选择总重量最 接近Wkg的。不过,我们如何才能不重复地穷举出这2^n种装法呢?这里就可以用回溯的方法。

我们可以把物品依次排列,整个问题就分解为了n个阶段,每个阶段对应一个物品怎么选择。先对第一个物品进行处理,选择装进去或 者不装进去,然后再递归地处理剩下的物品。描述起来很费劲,我们直接看代码,反而会更加清晰一些。

代码如下

package mainimport "fmt"//总的思想是,把n个物体依次排列
//对每个当前物体考虑两种情况,一种是不放进入背包后,递归遍历后边的各种情况
//另一种是放进入背包后,再递归遍历后边的各种情况
//出递归条件,已经访问了最后一个物体了或者已经是背包最大容量了var maxW int                              //表示背包能装的最大重量
var curAnswer []int                       //当前背包状态,下标表示物体,值表示是否装进背包
var bestAnswerMap = make(map[int][][]int) //存储最佳答案,key背包重量,值为多种情况,所以为数组func f(i, cw int, items []int, n, w int) {if curAnswer == nil { //其实只初始化了一次curAnswer = make([]int, n) //curAnswer[x]值为1,表示x加入背包}if cw == w || i == n {if cw != 0 && cw >= maxW { //cw是在背包允许的重量范围里的值,取其中最大值maxW = cw//如下是为了打印出最佳结果bst := make([]int, n)for j := 0; j < n; j++ {bst[j] = curAnswer[j]}if val, ok := bestAnswerMap[maxW]; ok {val = append(val, bst)bestAnswerMap[maxW] = val//map中的元素是不能寻址的,val,ok这种方式,拿到的是副本} else {temp := make([][]int, 0)temp = append(temp, bst)bestAnswerMap[maxW] = temp}//以上是为了打印出最佳结果}return}curAnswer[i] = 0        //考虑不放进入f(i+1, cw, items, n, w) //考虑不放入当前物体的情况if cw+items[i] <= w {curAnswer[i] = 1                 //考虑放进入背包f(i+1, cw+items[i], items, n, w) //考虑放入当前物体的情况}
}func main() {a := []int{1, 2, 3, 4, 10, 5, 6, 7, 8, 9}f(0, 0, a, 10, 10)fmt.Println(maxW)for k, v := range bestAnswerMap {fmt.Printf("key is %d, value is %v\n", k, v)fmt.Println("=======================")}
}

01背包问题-回溯法相关推荐

  1. c语言 用回溯算法解决01背包问题,回溯法解决01背包问题

    <回溯法解决01背包问题>由会员分享,可在线阅读,更多相关<回溯法解决01背包问题(21页珍藏版)>请在人人文库网上搜索. 1.回溯法解决01背包问题,回溯法解决01背包问题, ...

  2. 0-1背包问题—回溯算法—java实现

    0-1背包问题 [问题描述] 有n种可选物品1,-,n ,放入容量为c的背包内,使装入的物品具有最大效益. 表示 n :物品个数 c :背包容量 p1,p2, -, pn:个体物品效益值 w1,w2, ...

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

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

  4. 回溯法求解背包问题java_背包问题回溯法的递归实现(java)

    0-1背包问题,在搜索过程中使用递归来完成. package com.test; class Pack { int n = 8; //物品个数 int W = 110; //背包总容量 int[] W ...

  5. 01背包问题:图表法带你快速理解动态规划解决01背包问题 附C++源码

    0-1背包问题 所谓0-1背包问题,也就是给你一个重量为M的背包和n种物品,每种物品有一定的重量和价值,在每种物品均可装入背包1次或不装入(不能仅装入物品的一部分)且不超过背包载重量的前提下,问你怎样 ...

  6. 探讨与研究——动态规划算法、回溯法、分支限界法解0-1背包问题

    一个人终归是要成长的,是要不断历练的,没有人可以安安稳稳一辈子.就算是最有地位最有钱的人也要不断追求.不断历练.不断提升自己. 人的学问少时在不断学习,青年时期不断实践.随着时间推移,到了老年终有所成 ...

  7. 0-1背包问题(多解)

    0-1背包问题(多解) 问题 有n个物品,它们有各自的体积和价值,现有给定容量c的背包,如何让背包里装入的物品具有最大的价值总和? 贪心(错解) 贪心策略有三种,分别为价值贪心(优先选取价值最大的), ...

  8. 回溯法(深度优先)剪枝和分支限界法(宽度优先)剪枝对比:01背包问题

    限界函数: CurValue + rest <= BestValue 回溯法(深度优先)剪枝 # 递归方式 class pack_01_back_prune_test: def __init__ ...

  9. 限界分支法:01背包问题,优先级队列(包含解的追踪)

    前面提到: 不知道大家注意到没有?上述实现方式没有使用单位体积价值的排序,和之前提到01背包回溯法基于单位体积价值实现不一样(先装单位体积价值高的). 我们网上经常看到都是基于以上实现的,到底这个用有 ...

最新文章

  1. 截取年月日在hana中怎么写_写完作业就不学了怎么办?焦虑中的家长不妨先低头看看...
  2. 【CodeVS 1540】银河英雄传说 2002年NOI全国竞赛
  3. 使用VM Tools让VMware虚拟机里的ubuntu能够共享Windows系统的文件夹
  4. Android TextView长按复制实现,Android复制文本
  5. 每个做DBA的孩纸都是上辈子被drop的db
  6. Linux如何搭建Java部署环境
  7. linux下camera驱动分析_LINUX设备驱动模型分析之三 驱动模块相关(DRIVER)接口分析...
  8. 纯JS日历控件自动输入日期到TextBox、文本框当中
  9. 卷积神经网络交通标志识别
  10. HDU 5442 后缀自动机(从环字符串选定一个位置 , 时针或顺时针走一遍,希望得到字典序最大)...
  11. 数据库银行业务基础知识
  12. H5 授权微信第三方登录
  13. 异贝,通过移动互联网技术,为中小微实体企业联盟、线上链接、线上线下自定义营销方案推送。案例53
  14. python程序执行完后重头开始做烧饼_从“程序员转行卖烧饼”想到IT人创业
  15. 学界 | 大数据背景下,景观研究怎么做?
  16. 随机效应估算与固定效应估算_固定效应模型及估计原理说明.doc
  17. 告别纸质化办公,OA系统为企业节能提效
  18. 4g模块与51单片机通信
  19. 【SQL】Sql Server SQL语句学习
  20. Python 超简单格式化代码,仅需一行命令

热门文章

  1. THE ANATOMY OF AN INVITE REQUEST 解析一个invite request
  2. 非常恶俗地分享一首歌曲(群星·北京欢迎你)【附视频】
  3. 如何选择适合你的兴趣爱好(二十一),旅游
  4. RSA pkcs1与pkcs8 java获取私钥
  5. MCTK批处理MODIS L2 swath产品
  6. MPLS hub and spoke 实验问题
  7. 使用DDNS搭建Wireguard服务器的一个小问题
  8. Linux服务器运维管理 项目二 管理与维护Linux系统
  9. js判断网页在手机端跳转到移动页面,script怎么写跳转移动端
  10. c语言:青蛙出井问题程序