背景

  • 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. Java项目:在线课程会员系统(java+Springboot+Maven+JSP+Spring+Mysql+layui)
  2. matlab i型级联filter,Matlab中filter,conv,impz用法(最新整理)
  3. 算法---------数组-----------翻转单链表
  4. CentOS5 部署 戴尔OMSA
  5. MySQL 备份和恢复策略(二)
  6. Google Play应用上架流程(含踩坑经验)
  7. mysql好玩的代码_mysql的order by与where出现的好玩事
  8. Iterator(迭代器)--对象行为模式
  9. java编程思想2_《JAVA编程思想2》笔记
  10. C++ 领域:游戏、HPC、编译器、金融、财务
  11. 死磕jdk源码之如何注释
  12. cpda数据分析师证书含金量高吗
  13. python调用hive与java调用区别_使用Pyhive调用
  14. java浅_浅谈Java浅层复制和深层复制
  15. 对MC9S12XS128MAL中TIM、PIT、RTI的一点理解
  16. 到底要不要去外包公司?这篇带你全面了解外包那些坑!
  17. PySimpleGUI:快速开始
  18. 电信行业用户流失预测——你的用户会流失吗?
  19. 有限状态自动机(FSM)的一些逻辑
  20. 笔记:计算机视觉与深度学习-北邮-鲁鹏-2020年录屏-第一讲

热门文章

  1. html5开花动画效果代码,HTML5 Canvas藤曼系植物生长开花动画
  2. 毕业了----新的生活
  3. Packetix ***Client Linux端配置及加入***Server过程
  4. 安卓 元素渲染(类似v-for)
  5. SQLServer设置单词首字母大写
  6. 游戏开发防作弊以及原理
  7. Window添加悬浮窗解析
  8. 百练1002:方便记忆的电话号码(C++实现,北大软微)
  9. 在线手机计算机,qq电脑在线怎么显示手机在线
  10. CUBEMX+CANOPEN教程四:canopen小结