回溯法求0/1背包问题

一 实验目的

掌握回溯法的基本设计思想与原则。

二 实验内容

给定n个重量为w1,w2....wn的物品,其价值为v1,v2....vn;另有一个容量为C的背包,使用回溯法求这个物品中一个最有价值的子集使得在满足背包的容量的前提下,包内的总价值最大。

三、算法设计与编码

3.1问题分析

回溯法:通过深度优先搜索策略在问题的解空间树中系统的搜索一个问题的任一解或所有可能解;一种能避免不必要搜索的穷举式的搜索算法

“回溯”即采用试错的思想,在搜索尝试过程中寻找问题的解,当探索到某一步时,发现原先的选择并不满足求解条件,就退回一步(回溯)重新选择。

可行性分析:

在给定的重量和价值下,选取一组物品放入背包,使得背包中物品的总价值最大。而每个物品只能选择放入或者不放入背包,如果所有物品的重量之和超过了背包容量,则方案无法实施,需要回溯到上一步。而每一步的选择都会影响到最终的结果,因此这是一个典型的可以通过回溯法来求解的组合优化问题。

3.2算法设计

回溯法解决01背包问题的核心思路是深度优先搜索解空间树+剪枝:

1.定义问题的解空间:

解空间是由所有物品的可能装入方案组成的

2.建立解空间结构:

对于每一个物品i,对于该物品只有选与不选两个决策,总共有n个物品,可以顺序依次考虑每个物品,这样就形成了一棵解空间树。

3.回溯法以深度优先方式搜索解空间树并在搜索中用剪枝函数避免无效搜索:

可行性约数函数: cw+w[i]<=c---左剪枝判断

上界函数:cp+r<=bestp---右剪枝判断

 

步骤:

1.获取用户输入数据:

背包容量c、物品个数n、各物品重量weight[]和价值price[]

2.创建一个knapsack对象k,并调用其knapsack方法来计算输出最优价值bestp、被选中的物品序号;

Knapsack方法:

1)初始化数据

2)创建一个单位重量价值数组q,其中每个元素都是一个Element对象,包含物品编号和单位重量价值;对q数组按照单位重量价值从大到小排列。

3)重新构建p和w数组,将排序后的单位重量价值数组q中的单位重量价值赋值给p和w数组。

4)调用backtrack方法从第一个物品进行回溯搜索,寻找最优解。

在backtrack方法中,首先判断是否到达叶子节点(即所有物品都已处理完毕)如果是,则更新最优价值bestp和最优装入背包顺序bestx[],并返回。如果未到达叶子节点,则尝试将当前物品放入背包。如果当前物品可以完全放入背包(即剩余容量足够),则将其加入背包,并递归处理下一个物品。然后恢复现场,继续处理下一个物品;如果当前价值加上剩余物品的价值大于最优价值,则不将当前物品放入背包,继续处理下一个物品。

3.3核心代码

4b4343ab84e44046be94c3288329fa4f.png

fce7a5a1cf6b42f5b670f33f1393d4b7.png

四、算法运行调试与分析

测试:

f413ab55a3e040d38d6eacd87274044e.png

b2a9107b77764beb97a690a423f5833f.png

用户输入背包容量、物品数目、质量、价值,通过回溯法成功找到并输出装入背包的最优价值和装入背包的物品编号。

五 实验总结

本次实验,我用回溯法解决了01背包问题:通过单位重量价值数组对物品进行排序,再通过回溯法逐一试探,左右剪枝,直到找到最优解。这次实践加深了我对回溯法的核心思想(通过试探和回溯来寻找问题的解,当探索到某一步时,如果发现当前路径不能得到有效的解,则退回一步重新探索)的理解,提升了我分析问题并解决问题的能力。

 

  • 20
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

42341352315125115

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值