算法分析三(2)——用回溯法求解0-1背包问题

本文介绍了使用回溯法解决0-1背包问题的实验过程,包括实验目的、原理、步骤和关键代码。实验中,通过对物品按单位重量价值排序,结合上界函数进行剪枝,实现了在不同规模数据下的高效求解。实验结果显示,随着数据规模增大,运行时间相应增加,但剪枝策略有效降低了时间复杂度。
摘要由CSDN通过智能技术生成

pan.baidu.com/s/1w-VSMWmr9ntEWWdxZoD4Yw 
码:jnlh 

算法分析与设计

时间

2020.5.16

 实验名称

用回溯法求解0-1背包问题

实验目的

通过上机实验,要求掌握回溯算法的问题描述、算法设计思想、程序设计。

实验原理

给定任意几组数据,利用回溯算法的限界与剪枝的思想,求解0-1背包问题并输出答案。

实验步骤

 问题分析:

给定n种物品和一背包。物品i的重量是wi>0,其价值为vi>0,背包的容量为c。问应如何选择装入背包中的物品,使得装入背包中物品的总价值最大? (要求使用回溯法)

书上例题:

手动求解应该选择1、3、4三个物品,最优值为20;

 算法思想:

01背包属于找最优解问题,用回溯法需要构造解的子集树。对于每一个物品i,对于该物品只有选与不选2个决策,总共有n个物品,可以顺序依次考虑每个物品,这样就形成了一棵解空间树; 

基本思想就是遍历这棵树,以枚举所有情况,最后进行判断,如果重量不超过背包容量,且价值最大的话,该方案就是最后的答案。

在搜索状态空间树时,只要左子节点是可一个可行结点,搜索就进入其左子树。对于右子树时,先计算上界函数,以判断是否将其减去(剪枝)

上界函数bound():当前价值cw+剩余容量可容纳的最大价值<=当前最优价值bestp。 

为了更好地计算和运用上界函数剪枝,选择先将物品按照其单位重量价值从大到小排序,此后就按照顺序考虑各个物品。

 算法步骤:

① 将用例数据从文件中读取,初始化数据;

② 将物品按照单位重量的价值从大到小排序;

③ 进行操作如下:

利用回溯法试设计一个算法求出0-1背包问题的解,也就是求出一个解向量Xi(即对n个物品放或不放的一种的方案)

其中, (Xi= 0 或1,Xi = 0表示物体i不放入背包,Xi =1表示把物体i放入背包)。

从第0层开始进行递归函数Backtrack,

  当i>n时,算法搜索至叶子结点,得到一个新的物品装包方案,此时算法适时更新当前的最优价值最优解

  当i<n时,当前扩展结点位于排列树的第(i-1)层,此时算法选择下一个要安排的物品,以深度优先方式递归的对相应的子树进行搜索,对不满足上界约束的结点,则剪去相应的子树。

④当整个解空间树遍历完成则输出最优值与最优解;

关键代码

关键代码(带注释)

1. 初始化函数init()

 

   输入背包容量、物品总数、物品价值重量等数据,求出每一个物品的单位重量的价值,根据该单价进行从大到小的排序;

2. 求上界函数bound(用于剪枝)

   按照剩余物品的单价将背包的剩余容量塞满(可塞一个物品的一部分),塞满后的背包内的物品总价值即为上界,若该上界小于当前最优值则剪枝;

3. 计算时间部分代码

通过时间函数QueryPerformanceFrequency与cpu的主频频率得到程序段的运行时间,可以精确到微妙,比clock函数更精确一些;

4. 随机数生成程序

利用rand()函数生成大小为10、100、1000的三个文件,其中全为随机数;

3、4两个部分与之前的实验所用方法相同;

5. 回溯函数(核心部分)

如果当前层达已处理完最后一个物品,则说明当前的价值比现在的最优值要大,因此更新最优值与最优解;

如果当前层未处理完最后一个物品,则如果当前物品可放入背包则直接进入左子树,如果右子树(不放入当前物品)的上界大于当前最优值则可以进入右子树;

测试结果

运行结果截图及分析

对于课本样例:

  运行结果正确;

对于三种不同规模的文件(10、100、1000):

可以看到对三种规模的文件进行测试的结果,数据规模越大则时间越长;

因为剪枝的原因看不出其O(2^n)的时间复杂度;

时间复杂度分析:

该问题为回溯法的子集树问题,对每一个物品都有放入与不放两种决策,因此遍历解空间树的时间复杂度未O(2^n);

实验心得

通过这次实验,我回顾了回溯算法的基本原理,回溯法的剪枝与限界方法在本问题中有着清晰简洁的体现,加深了我对它们的使用的熟练度。为更难更深层次的问题的回溯法求解打下基础。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值