01背包问题

递归方式模板:

void backtrack(int t){   if(t > n) output(x);   else{   for(int i = f(n,t); i <= g(n,t);i++){   x[t] = h(i);   if(constraint(t) && bound(t)) backtrack(t+1);   }   }
}

递归实现:分成3个部分,为了使用限界函数,需要把数据降序排序,限界函数,以及回溯函数。

def pack_01_back_prune(N,V,C,W):BestResult = [False]*NSelected = [False]*(N)BestValue = [0]CurCost = [0]CurValue = [0]order = [i for i in range(N)]perp = [0]*N# sorted by value per weightdef sort_group(C,W,O):perp = [0]*Nfor i in range(N):perp[i] = W[i]/C[i]for i in range(N-1):for j in range(i+1,N):if  perp[i] < perp[j]:temp = perp[i]perp[i] = perp[j]perp[j] = temptemp = O[i]O[i] = O[j]O[j] = temptemp = C[i]C[i] = C[j]C[j] = temptemp = W[i]W[i] = W[j]W[j] = temp                    return perp,C,W,O
#   计算上界函数,功能为剪枝
#  判断当前背包的总价值cp+剩余容量可容纳的最大价值<=当前最优价值def bound(depth):left_weight = V - CurCost[0]b = CurValue[0] while depth < N and C[depth] <= left_weight:left_weight -=C[depth]b += W[depth]depth +=1if depth < N:b += perp[depth] * left_weightreturn bdef backtracking(depth):if depth > N-1:if CurValue[0] > BestValue[0]:BestValue[0] = CurValue[0]                BestResult[:] = Selected[:]else:
#    如若左子节点可行,则直接搜索左子树;
#    对于右子树,先计算上界函数,以判断是否将其减去if CurCost[0] + C[depth] <= V :# and bound(depth+1) > BestValue[0]:Selected[depth] = TrueCurCost[0] += C[depth]CurValue[0]  += W[depth]# nextbacktracking(depth+1)# undoCurCost[0] -= C[depth]CurValue[0]  -= W[depth]
#           如若符合条件则搜索右子树     if bound(depth+1) > BestValue[0]:Selected[depth] = Falsebacktracking(depth+1)perp,C,W,order = sort_group(C,W,order)backtracking(0)# 把结果恢复成原来顺序decode_BestResult =[False]*Nfor i in range(N):if BestResult[i]:decode_BestResult[order[i]] = Truereturn decode_BestResult,BestValue

迭代方式,顺序执行,注意一点,就是不满足限界函数时,需要提前进入回溯

#%%def pack_01_back_prune_iteration(N,V,C,W):BestResult = [False]*NSelected = [False]*(N)BestValue = [0]CurCost = [0]CurValue = [0]order = [i for i in range(N)]perp = [0]*N# sorted by value per weightdef sort_group(C,W,O):perp = [0]*Nfor i in range(N):perp[i] = W[i]/C[i]for i in range(N-1):for j in range(i+1,N):if  perp[i] < perp[j]:temp = perp[i]perp[i] = perp[j]perp[j] = temptemp = O[i]O[i] = O[j]O[j] = temptemp = C[i]C[i] = C[j]C[j] = temptemp = W[i]W[i] = W[j]W[j] = temp                    return perp,C,W,O
#   计算上界函数,功能为剪枝
#  判断当前背包的总价值cp+剩余容量可容纳的最大价值<=当前最优价值def bound(depth):left_weight = V - CurCost[0]b = CurValue[0] while depth < N and C[depth] <= left_weight:left_weight -=C[depth]b += W[depth]depth +=1if depth < N:b += perp[depth] * left_weightreturn bdef backtracking_iteration(depth):while True:if depth < N:# 进入1的分支if CurCost[0] + C[depth] <= V and bound(depth+1) > BestValue[0]:Selected[depth] = TrueCurCost[0] += C[depth]CurValue[0]  += W[depth]# 进入0的分支elif bound(depth+1) > BestValue[0]:Selected[depth] = False# 不满足限界函数,回溯    else:while depth >= 0 and not Selected[depth]:depth -=1if depth < 0:breakelse:Selected[depth] =FalseCurCost[0] -= C[depth]CurValue[0]  -= W[depth]                     else:if CurValue[0] > BestValue[0]:BestValue[0] = CurValue[0]                BestResult[:] = Selected[:]# 到底部回溯,这时候,depth已经穿了depth -=1while depth >= 0 and not Selected[depth]:depth -=1if depth < 0:breakelse:Selected[depth] =FalseCurCost[0] -= C[depth]CurValue[0]  -= W[depth]        depth +=1perp,C,W,order = sort_group(C,W,order)backtracking_iteration(0)decode_BestResult =[False]*Nfor i in range(N):if BestResult[i]:decode_BestResult[order[i]] = Truereturn decode_BestResult,BestValue

输出结果

#%%
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(N,V,C,W)
#print pack_01_back_iteration(N,V,C,W)
#print pack_01_back_iteration2(N,V,C,W)
print pack_01_back_prune(N,V,C,W)
print pack_01_back_prune_iteration(N,V,C,W)runfile('/root/test/back_tracking.py', wdir='/root/test')
([False, True, True, True, False, True, False, True], [39.0])runfile('/root/test/back_tracking.py', wdir='/root/test')
([False, True, True, True, False, True, False, True], [39.0])

还有一种分支限界的思路,上界函数为:CurValue + rest <= BestValue:

# 这种解法注意回溯函数一致性,思路比较清晰:满足剪枝条件就回溯:CurValue + rest <= BestValue
def pack_01_back_iteration3(N,V,C,W):depth = 0BestResult = [False]*NSelected = [False]*(N)BestValue = 0CurCost = 0CurValue = 0   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 +=1if depth >= N:BestValue = CurValue                BestResult[:] = Selected[:]else:rest -=W[depth]Selected[depth] =Falsedepth +=1while CurValue + rest <= BestValue:depth -=1while depth >=0 and not Selected[depth]:rest +=W[depth]depth -=1if depth < 0:return BestResult,BestValueelse:Selected[depth] =FalseCurCost -= C[depth]CurValue  -= W[depth]depth +=1N = 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_iteration3(N,V,C,W)([False, True, True, True, False, True, False, True], 39.0)

01背包问题:回溯法和限界分支、递归和迭代方式相关推荐

  1. 货郎问题:回溯法和限界分支法

    这个问题可以堪称一个全排列,[起点,剩下的全排列] 回溯法 import numpy as npclass backtracking_Traveling_saleman:# 初始化,明确起点def _ ...

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

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

  3. 限界分支法(队列方式)追踪解:01背包问题

    追踪解 追踪解,上述实现的情况下,解都在最后一层,根本不知道之前的路径是怎样的,广度优先搜索,同一个纬度,假如不加指标判断的话,根本不知道最优解是选择的哪一个,所以需要同一个纬度的每一个结点,记住他之 ...

  4. 01背包问题-回溯法

    背景 0-1背包是非常经典的算法问题,很多场景都可以抽象成这个问题模型.这个问题的经典解法是动态规划. 不过还有一种简单但没有那么高效的解法,这里用的回溯算法. 0-1背包问题有很多变体,我这里介绍一 ...

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

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

  6. 限界分支法优先级队列方式出口和追踪解的两种方法总结

    在优先级队列分支限界法法中,何时为出接口,也就是while循环何时退出了? 解空间为[0,1,2-,n-1],当depth = n-1时,就可以记录结果了,可以考虑循环体退出了(实际上能不能出,还要看 ...

  7. 分治:分治和动态规划的区别,二分检索递归和迭代方式实现

    分治法 分治一般可以直接使用递归实现,在不考虑空间消费的情况下和迭代方式时间消耗相差不多 ======================================================= ...

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

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

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

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

最新文章

  1. LiveVideoStackCon讲师热身分享第一季
  2. 计算机辅助抗体设计,计算机辅助设计提高单克隆抗体亲和力的研究
  3. c语言答辩题目,中学数学《线的认识》答辩题目与解析
  4. java runnable 异常_Java实现多线程异常捕获Runnable的案例
  5. seaborn—seaborn.regplot绘制线性回归拟合图
  6. [Search Engine] 搜索引擎技术之查询处理
  7. 简析通达信股票接口测试过程
  8. pr电影混剪思路及常用快捷键
  9. VegaFEM免费试用
  10. OEL安装RAC 配置DNS文档
  11. 您选择的分区不支持无损调整容量操作
  12. android之资源颜色汇总
  13. java-之冒泡排序法
  14. 解决 Win 10 ipv6无网络权限/无Internet连接权限 问题
  15. 4.4OC10-内存管理2-set方法的内存管理
  16. 史上最通熟易懂的检索式聊天机器人讲解
  17. 乐忧商城项目总结-4
  18. 3D建模入门看什么书?怎么才能高效有技巧学习
  19. MFC之系统任务栏 获取Windows桌面底部任务栏自动隐藏任务栏\取消自动隐藏任务栏 的消息
  20. 多框文件夹浏览器Q-Dir

热门文章

  1. eclipse jsp没有提示_JSP+Struts2+JDBC+Mysql实现的校园宿舍管理系统
  2. 为什么说_br__标签需要闭合
  3. 未指定发送trap的源接口_组播之RPF接口检测
  4. android镜像文件怎么命名,android镜像文件说明(示例代码)
  5. swingbench oracle rac,使用Swingbench压力测试Oracle RAC
  6. outlook 未安装信息服务器,Outlook Web Access 未初始化并且在客户端访问服务器上的应用程序日志中记录了事件 ID 64...
  7. linux shell命令分布执行,Linux学习笔记:bash特性之多命令执行,shell脚本
  8. java中什么是类型_什么是Java中基本数据类型?
  9. java获取数据库MetaData
  10. java闪屏怎么制作,Java Swing创建自定义闪屏:在闪屏下画进度条(一)