首页 > 其他分享 >动态规划之 附录二:背包问题的搜索解法

动态规划之 附录二:背包问题的搜索解法

时间:2023-06-30 21:13:20浏览次数:39  
标签:剪枝 背包 cur 问题 搜索 子集 附录 解法

《背包问题九讲》的本意是将背包问题作为动态规划问题中的一类进行讲解。但鉴于的确有一些背包问题只能用搜索来解,所以这里也对用搜索解背包问题做简单介绍。大部分以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的方程,只好写搜索以谋求一定的分数了。

标签:剪枝,背包,cur,问题,搜索,子集,附录,解法
From: https://www.cnblogs.com/shoshana-kong/p/17517819.html

相关文章

  • 动态规划之 附录一:USACO中的背包问题
    USACO是USAComputingOlympiad的简称,它组织了很多面向全球的计算机竞赛活动。USACOTrainng是一个很适合初学者的题库,我认为它的特色是题目质量高,循序渐进,还配有不错的课文和题目分析。其中关于背包问题的那篇课文(TEXTKnapsackProblems)也值得一看。另外,USACOContest是US......
  • 动态规划之 背包问题问法的变化
    以上涉及的各种背包问题都是要求在背包容量(费用)的限制下求可以取到的最大价值,但背包问题还有很多种灵活的问法,在这里值得提一下。但是我认为,只要深入理解了求背包问题最大价值的方法,即使问法变化了,也是不难想出算法的。例如,求解最多可以放多少件物品或者最多可以装满多少背包的空......
  • 动态规划之有依赖的背包问题
    简化的问题这种背包问题的物品间存在某种“依赖”的关系。也就是说,i依赖于j,表示若选物品i,则必须选物品j。为了简化起见,我们先设没有某个物品既依赖于别的物品,又被别的物品所依赖;另外,没有某件物品同时依赖多件物品。算法这个问题由NOIP2006金明的预算方案一题扩展而来。遵从该题......
  • 动态规划之分组的背包问题
    问题有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。算法这个问题变成了每组物品有若干种策略:是选择本组的某一件,还是......
  • 动态规划之混合三种背包问题
    问题如果将P01、P02、P03混合起来。也就是说,有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包)。应该怎么求解呢?01背包与完全背包的混合考虑到在P01和P02中给出的伪代码只有一处不同,故如果只有两类物品:一类物品只能取一次,另一类......
  • 2023-06-30《计算方法》- 陈丽娟 - 线性方程组的迭代解法.md
    2023-06-30《计算方法》-陈丽娟-线性方程组的迭代解法Matlab计算方法JacobiGauss-SeidelSORSSOR定常迭代法所谓迭代法实际上是求解一个关于映射的不动点问题:然后利用构造一个迭代格式这里表示T的一个复合函数,其可能随迭代次数而改变,最终目标即是得到.下面我们给出收敛......
  • 第三讲 多重背包问题
    题目有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。基本算法这题目和完全背包问题很类似。基本的方程只需将完全背包问题的方程略微一改即可,因为对于第i种物......
  • 第一讲 01背包问题
    题目有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。基本思路这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值......
  • 动态规划-背包问题-完全背包问题:leetcode 377. 组合总和 Ⅳ
    1.题目读题给你一个由不同整数组成的数组nums,和一个目标整数target。请你从nums中找出并返回总和为target的元素组合的个数。题目数据保证答案符合32位整数范围。 示例1:输入:nums=[1,2,3],target=4输出:7解释:所有可能的组合为:(1,1,1,1)(1,1,2)(1,2,......
  • 动态规划 完全背包问题 -游戏最大伤害
     1.题目读题 游戏角色,有技能列表和魔法值,求能造成的最大伤害,例如:输入skill_list:[{mana_cost:10,damage:10},{mana_cost:12,damage:13}],current_mana:20,输出max_damage:20输入skill_list:[{mana_cost:10,damage:10},{mana_cost:12,damage:13}],current......