`
com_xpp
  • 浏览: 352946 次
社区版块
存档分类
最新评论

P11: 背包问题的搜索解法

 
阅读更多

P11: 背包问题的搜索解法

《背包问题九讲》的本意是将背包问题作为动态规划问题中的一类进行讲解。但鉴于的确有一些背包问题只能用搜索来解,所以这里也对用搜索解背包问题做简单介绍。大部分以01背包为例,其它的应该可以触类旁通。

简单的深搜

对于01背包问题,简单的深搜的复杂度是O(2^N)。就是枚举出所有2^N种将物品放入背包的方案,然后找最优解。基本框架如下:

procedure SearchPack(i,cur_v,cur_w)
    if(i>N)
        if(cur_w>best)
            best=cur_w
        return
    if(cur_v+v[i]<=V)
        SearchPack(i+1,cur_v+v[i],cur_w+w[i])
    SearchPack(i+1,cur_v,cur_w)

其中cur_v和cur_w表示当前解的费用和权值。主程序中调用SearchPack(1,0,0)即可。

搜索的剪枝

基本的剪枝方法不外乎可行性剪枝或最优性剪枝。

可行性剪枝即判断按照当前的搜索路径搜下去能否找到一个可行解,例如:若将剩下所有物品都放入背包仍然无法将背包充满(设题目要求必须将背包充满),则剪枝。

最优性剪枝即判断按照当前的搜索路径搜下去能否找到一个最优解,例如:若加上剩下所有物品的权值也无法得到比当前得到的最优解更优的解,则剪枝。

搜索的顺序

在搜索中,可以认为顺序靠前的物品会被优先考虑。所以利用贪心的思想,将更有可能出现在结果中的物品的顺序提前,可以较快地得出贪心地较优解,更有利于最优性剪枝。所以,可以考虑将按照“性价比”(权值/费用)来排列搜索顺序。

另一方面,若将费用较大的物品排列在前面,可以较快地填满背包,有利于可行性剪枝。

最后一种可以考虑的方案是:在开始搜索前将输入文件中给定的物品的顺序随机打乱。这样可以避免命题人故意设置的陷阱。

以上三种决定搜索顺序的方法很难说哪种更好,事实上每种方法都有适用的题目和数据,也有可能将它们在某种程度上混合使用。

子集和问题

子集和问题是一个NP-Complete问题,与前述的(加权的)01背包问题并不相同。给定一个整数的集合S和一个整数X,问是否存在S的一个子集满足其中所有元素的和为X。

这个问题有一个时间复杂度为O(2^(N/2))的较高效的搜索算法,其中N是集合S的大小。

第一步思想是二分。将集合S划分成两个子集S1和S2,它们的大小都是N/2。对于S1和S2,分别枚举出它们所有的2^(N/2)个子集和,保存到某种支持查找的数据结构中,例如hash set。

然后就要将两部分结果合并,寻找是否有和为X的S的子集。事实上,对于S1的某个和为X1的子集,只需寻找S2是否有和为X-X1的子集。

假设采用的hash set是理想的,每次查找和插入都仅花费O(1)的时间。两步的时间复杂度显然都是O(2^(N/2))。

实践中,往往可以先将第一步得到的两组子集和分别排序,然后再用两个指针扫描的方法查找是否有满足要求的子集和。这样的实现,在可接受的时间内可以解决的最大规模约为N=42。

搜索还是DP?

在看到一道背包问题时,应该用搜索还是动态规划呢?

首先,可以从数据范围中得到命题人意图的线索。如果一个背包问题可以用DP解,V一定不能很大,否则O(VN)的算法无法承受,而一般的搜索解法都是仅与N有关,与V无关的。所以,V很大时(例如上百万),命题人的意图就应该是考察搜索。另一方面,N较大时(例如上百),命题人的意图就很有可能是考 察动态规划了。

另外,当想不出合适的动态规划算法时,就只能用搜索了。例如看到一个从未见过的背包中物品的限制条件,无法想出DP的方程,只好写搜索以谋求一定的分数了。

分享到:
评论

相关推荐

    背包问题 数学建模 背包问题 数学建模

    背包问题: 01背包问题 02: 完全背包问题 03: 多重背包问题 04: 混合三种背包问题 05: 二维费用的背包问题 06: 分组的背包问题 07: 有依赖的背包问题 08: 泛化物品 09: 背包问题问法的变化 11: 背包问题的搜索解法

    背包问题九讲及各种解法

    背包问题的各种解法,以及背包问题的一些推导过程,再加上扩展的背包问题,很不错的教程

    0-1背包问题多种解法

    0-1背包问题的多种解法,包括暴力求解、动态规划求解、回溯法、贪心法求解求解、模拟退火算法,C++源代码,有详细的注释

    算法课程:背包问题

    背包问题(Knapsack problem)是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最...

    背包问题的贪心算法,背包问题的贪心解法

    算法,背包问题,贪心算法 讲述背包问题。对于学习这一部分的学习者,可以起作用。

    实验五:01背包问题的回溯算法设计

    实验目的:0/1背包问题的回溯算法设计 实验原理:回溯算法设计。 实验要求:基本掌握回溯算法设计的原理方法。熟练掌握VC++中编程实现算法的常用技术和方法。 算法思想: 0-1背包问题:给定n种物品和一背包.物品i的...

    算法:背包问题总结(网上资料)

    作者比较完整地介绍了背包问题。感谢作者,所有内容归原作者所有。

    ACM经典题解析:背包问题

    ACM的经典题,背包问题,初学ACM的ACMER可以看看

    01背包问题的树搜索解法,分支界限法

    01背包问题的树搜索解法,分支界限法,适合初学者参考

    0-1背包问题的3种详细解法和比较

    0-1背包问题的3种详细解法和比较 详细讲解了0-1背包问题的动态规划 回溯法 分支界限法的解法 及其比较

    背包九讲 word版

    背包九讲: P01:01背包问题 P02:完全背包问题 P03:多重背包问题 P04:混合三种背包问题 P05:二维费用的背包问题 P06:分组的背包问题 P07:有依赖的背包问题 P08:泛化物品 P09:背包问题问法的变化

    信息学奥赛背包问题九讲

    信息学奥赛背包问题九讲,内容齐全第一讲 01背包问题 第二讲 完全背包问题 第三讲 多重背包问题 第四讲 混合三种背包问题 第五讲 二维费用的背包问题 第六讲 分组的背包问题 ...附录二:背包问题的搜索解法

    背包问题的各种算法实现

    目录 第一讲 01背包问题 第二讲 完全背包问题 第三讲 多重背包问题 第四讲 混合三种背包问题 第五讲 二维费用的背包问题 第六讲 分组的背包问题 第七讲 有依赖的背包问题 ...附录二:背包问题的搜索解法

    背包问题的若干种解法

    关于背包问题的多种解法,过程详细,用了动态规划和蛮力法求解

    背包问题9讲

    第1讲:背包问题 第二讲:完全背包问题 第3讲:多重背包问题 第4讲:混合三种背包问题 共9讲

    背包问题的遗传算法解法

    本程序利用遗传算法来求解背包问题.采用二进制字符串编码,1表示选择物体,0则不选择. 背包问题描述:在M件物品取出若干件放在空间为W的背包里,每件物品的重量为W1,W·2……Wn,与之相对应的价值为P1,P2……Pn。求...

    禁忌搜索背包问题,禁忌搜索算法解决背包问题,matlab

    用禁忌搜索算法求解背包问题。假设背包容量一定,已知每种物品的体积和价值,求出使价值最大的最优解。

    遗传算法解决01背包问题分析及代码

    01背包问题属于组合优化问题的一个例子,求解01背包问题的过程可以被视作在很多可行解当中求解一个最优解。01背包问题的一般描述如下: 给定n个物品和一个背包,物品i的重量为Wi,其价值为Vi,背包的容量为C。选择...

Global site tag (gtag.js) - Google Analytics