限界函数:

CurValue + rest <= BestValue

回溯法(深度优先)剪枝

# 递归方式
class pack_01_back_prune_test:        def __init__(self,N,V,C,W):self.num =Nself.V = Vself.C = Cself.W = Wself.BestResult = [False]*Nself.Selected = [False]*Nself.BestValue = 0self.CurCost = 0self.CurValue = 0# bound()限界函数self.rest = 0for i in range(N):self.rest += W[i]def pack_01_back_tracking(self,depth):if depth > self.num-1:if self.CurValue > self.BestValue:self.BestValue = self.CurValue               self.BestResult[:] = self.Selected[:]else:# 满足约束条件和限界函数的处理if self.CurCost + self.C[depth] <= self.V and self.CurValue + self.rest > self.BestValue:self.Selected[depth] = Trueself.CurCost += self.C[depth]self.CurValue  += self.W[depth]self.rest -= self.W[depth]# nextself.pack_01_back_tracking(depth+1)# undoself.CurCost -= self.C[depth]self.CurValue  -= self.W[depth]self.rest += self.W[depth]# 满足限界函数   if self.CurValue + self.rest > self.BestValue:self.Selected[depth] = Falseself.pack_01_back_tracking(depth+1)def print_Result(self):self.pack_01_back_tracking(0)print(self.BestResult)print(self.BestValue)                # 迭代方式
#%%
# 这种解法注意回溯函数一致性,思路比较清晰:满足剪枝条件就回溯:CurValue + rest <= BestValue
# 这是基于深度优先搜索的回溯法剪枝,以下是迭代实现方法
def pack_01_back_prune_iteration_test(N,V,C,W):depth = 0BestResult = [False]*NSelected = [False]*(N)BestValue = 0CurCost = 0CurValue = 0   # bound()限界函数rest = 0for i in range(N):rest += W[i]while True:# 尽量向左走直到不满足约束条件while depth < N and CurCost + C[depth] <= V:rest -=W[depth]Selected[depth] = TrueCurCost += C[depth]CurValue  += W[depth]depth +=1# 走到底,结果处理if depth >= N:BestValue = CurValue                BestResult[:] = Selected[:]# 不能往左走,就向右走,注意这里只是走一步而已else:rest -=W[depth]Selected[depth] =Falsedepth +=1# 当不满足限界函数的时候,就需要回溯,注意底部也满足这个条件while CurValue + rest <= BestValue:# 回溯的处理,之所有需要depth -=1,上面走的时候都depth++了,底部也是这样depth -=1while depth >=0 and not Selected[depth]:rest +=W[depth]depth -=1# 当回溯到root的之后,无法回溯了,输出结果if depth < 0:return BestResult,BestValue# 回溯恢复现场else:Selected[depth] =FalseCurCost -= C[depth]CurValue  -= W[depth]depth +=1
# 运行
N = 8
V = 30
C = [11,2,3,9,13,6,15,7,19]
W = [5.0,2.0,5.0,7.0,5.0,11.0,6.0,14.0]print(pack_01_back_prune_iteration_test(N,V,C,W))pack_01_back_prune_test(N,V,C,W).print_Result()       ([False, True, True, True, False, True, False, True], 39.0)
[False, True, True, True, False, True, False, True]
39.0

分支限界法(宽度优先)剪枝

也使用一样的限界函数:
CurValue + rest <= BestValue
回溯法深度优先很快就能得到一个可行解,进而可以更新BestValue,分支限界法宽度优先,可行解都在最后一层,BestValue一直得不到更新,那就是限界函数一直不起作用
为了使限界函数早生效,我们应该提前更新BestValue,在满足约束条件下,进入左子树就可以更新BestValue,因为最终的BestValue是满足约束条件下Curvalue里面的最大值

代码实现:

#%%
class FIFO_01_Pack_prune:def __init__(self,N,V,C,W):self.num =Nself.Volume = Vself.Cost = Cself.Value = Wself.BestValue = 0#用于存放活结点,便于理解,把根结点,以及第0层结束标志-1放进去# 结点包括2个属性:当前空间大小,当前的价值大小self.queue = [[0,0],[-1,-1],]  # 当前剩余价值和,bound()限界函数self.rest = 0# 把第一个减去,因为我们要在进入这一层前更新restfor i in range(1,N):self.rest += W[i]# 实现时叶子结点不加入到活结点列表def enQueen(self,pair,depth):if depth < self.num -1:self.queue.append(pair)def pack_01(self):
#        selected = [0]*self.num      # 首先取出根结点depth = 0pair = self.queue.pop(0)CurCost = pair[0]CurValue = pair[1]while True:# 判断左结点能否加入到队列,能的话,把当前空间和当前价值放入队列,满足约束条件if CurCost + self.Cost[depth] < self.Volume:# 满足限界函数if CurValue + self.Value[depth] + self.rest > self.BestValue:# 在进入左子树时,更新bestvalueself.BestValue = CurValue + self.Value[depth]                   self.enQueen([CurCost + self.Cost[depth],CurValue + self.Value[depth]],depth)# 右满足限界函数if CurValue + self.Value[depth] + self.rest > self.BestValue:self.enQueen([CurCost,CurValue],depth)# 然后弹出下一个结点pair = self.queue.pop(0)CurCost = pair[0]CurValue = pair[1]# 当同一层处理完毕时,先判断是否能够输出结果,判断的标准是队列是否为空,# 这时下一层的所有结点已经加入了队列,这时需要把下一层# 增加一个结尾-1便于判断,然后进入下一层,弹出下一个结点if CurCost == -1:if not self.queue:return self.BestValueself.enQueen([-1,-1],depth)depth += 1# 在刚进入下一层时,更新restself.rest -= self.Value[depth]# 弹出下一个结点pair = self.queue.pop(0)CurCost = pair[0]CurValue = pair[1]def print_Result(self):print(self.pack_01())                #%%
N = 8
V = 30
C = [11,2,3,9,13,6,15,7,19]
W = [5.0,2.0,5.0,7.0,5.0,11.0,6.0,14.0]#pack_01_back_test(N,V,C,W).print_Result()
FIFO_01_Pack_prune(N,V,C,W).print_Result()

不知道大家注意到没有?上述实现方式没有使用单位体积价值的排序,和之前提到01背包回溯法基于单位体积价值实现不一样(先装单位体积价值高的)。

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

  1. 回溯法--深度优先搜索

    1.概念 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就"回溯"返回,尝试别的路径. 回溯法是一种选优搜索法,按选优条件 ...

  2. 回溯法求地图填色实验(剪枝)

    回溯法求地图填色(剪枝) 文章目录 回溯法求地图填色(剪枝) (一) 问题求解 思维风暴(之前瞎想的,可以跳过) (二)算法思想:回溯 伪代码: 时间复杂度分析: (三)剪枝方向 1. 下层节点选取 ...

  3. 迷宫问题 深度优先搜索 广度优先搜索 宽度优先搜索【python】

    文章目录 一.实验内容 二.深度优先搜索和广度优先搜索总结 1.深度优先搜索算法 2.广度优先搜索算法 三.实验代码和用于测试的迷宫 1.实验代码 2.测试迷宫 2.1 maze1.txt 2.2 m ...

  4. 回溯法(算法分析与设计)

    0.回溯法的算法框架 A.简介 回溯法,又称试探法.一般需要遍历解空间,时间复杂度概况:子集树Ω(2^n),排序树Ω(n!),暴力法 B.回溯法解题三步骤 1)定义问题的解空间 如0-1背包问题,当n ...

  5. 基于深度优先搜索回溯法的人狼羊菜过河模型

    基于深度优先搜索回溯法的人狼羊菜过河模型 本文介绍一个农夫过河的小模型,算法 Python 实现,感觉还挺有趣的,因原为笔者课程作业论文改版而来,所以文章内容比起其他博客文章可能会比较严肃与严谨.期待 ...

  6. 算法分析五:回溯法与分⽀限界法

    一.回溯法 1. 基本思想与解题步骤 基本思想: 把问题的解空间转化成了图或者树的结构表⽰,然后使⽤深度优先搜索策略进⾏遍历,遍历的过程中记录和寻找所有可⾏解或者最优解. 解题步骤: 针对所给问题,定 ...

  7. 算法设计与分析 实验三 回溯法求解地图填色问题

    回溯法求解地图填色问题 一.实验目的与要求 1.实验基本要求: 2.实验亮点: 二.实验内容与方法 三.实验步骤与过程 1.未优化的回溯: (1)算法描述: (2)编程实现 (3)运行并测试: 2.对 ...

  8. 回溯法 | 求解装载问题

    问题描述: 有 n 个集装箱要装上一艘载重量为 W 的轮船,其中集装箱 i (1<=i<=n) 的重量,为wi.子啊装在体积不受限制的情况下,将尽可能重的集装箱装上轮船,当重量相同时要求选 ...

  9. 图的m着色问题——回溯法及其优化(变量排序MRV, 值排序MCV, 前向检查ForwardChecking, 智能回溯, 边相容,K阶相容)python C++实现

    文章目录 图的m着色问题背景 背景知识 问题描述 回溯法的原理及其实现 回溯法基本思想 朴素回溯法解决图的m着色问题 回溯优化策略 回溯法优化--变量排序MRV 回溯法优化--值排序MCV 回溯法优化 ...

最新文章

  1. 十五个常用的 Laravel 集合(Collection)
  2. [转] 视频直播前端方案
  3. Laravel5.5之事件监听、任务调度、队列
  4. 第一节:别出心裁的HTML5简介
  5. 一文看懂阿里、京东、滴滴大数据架构变迁
  6. 扫描二维码后可以自动跳转到网页
  7. 解决bootstrap中模态框打开时页面发生一瞬间移动
  8. 【Ci24R1小尺寸 DFN8/2*2】2.4G双向系统超低成本之选
  9. 腾讯云服务器性能评测:配置参数16核 32G 28M
  10. 微信app支付功能-服务端的实现-python3版
  11. 苹果App Store 应用商店页面的优化技巧
  12. markdown及IDEA快捷键
  13. Java实验01 Java编程基础(猜数字游戏、随机点名器)
  14. 视神经萎缩学计算机专业好吗,治视神经萎缩的维生素 视神经萎缩有哪些症状...
  15. 使用jQuery来锁定HTML表格中的首行和首列
  16. 生物信息学算法之Python实现|Rosalind刷题笔记:002 中心法则:转录
  17. 下一代LMS的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  18. 找谷歌地图上任意点的经纬度
  19. C#报错:试图加载格式不正确的程序 0x8007000b
  20. 小米汽车发售,竟然不到5000元,年轻人的第一辆汽车!

热门文章

  1. android旋转动画开源库,android 围绕中心旋转动画
  2. Mac解决终端显示乱码
  3. php 安全设置总结。
  4. with open新创建的文件在哪找_Python 简明教程——24,Python 文件读写
  5. 头部玩家指的是什么_MMO等级提升背后:如何设计经验,才能使玩家达成预期时间曲线?...
  6. 【nginx】return 301 302 重定向URL
  7. 【Tomcat】解决GET方式传递的参数(URL中的参数)乱码问题
  8. spring cloud Hystrix
  9. discuz misc.php慢,discuz提示misc.php?mod=patchaction=导致网站访问慢问题解决办法
  10. dederss.php美国与,Dede经验:全站rss/连载和分类首页模板替换