Knapsack(背包)问题
Problem:给定n件物品,每一件物品有价值vi和重量wi,给定一个容量为W的箱子,要求用在不超过箱子容量的前提下,装入价值尽可能多的物品。
这个问题分为两个版本,一种是fractional,即每件物品是可拆分的,另一种是01类型的,即每件物品要么全拿要么不拿。
Fractional版本:这个版本的问题存在得到最优解的贪心算法,属于P问题,即多项式可解。
贪心算法:按照对物品进行降序排序,放入背包中,使得背包充满。这个算法考虑每一价值的带价,选取性价比最高的物品优先放入,那么最后一件物品可能只会放入部分。现实中的问题表现为考试,假设我们计算每一题的时间不同,比如第一题是三角函数,第二题是解析几何,那么在相同分数的情况下,我们会选择先做三角函数(花费时间更少)。最后的解析几何能做多少就多少,按做出部分给分(对应fractional)。
01版本:属于NPC问题,只存在approximation算法。Approximation分两种思路,DP解法和贪心算法,先看贪心算法
贪心算法:
(1) 按照对物品进行降序排序,假设新的顺序为物品1,物品2…物品n
(2) 找到k使得 前k个物品的重量不大于W,前k+1个大于W
(3) 设S1 = 前k个物品的价值和, S2 =第k+1个物品的价值, V=max (S1, S2)
(4) return V
这是一个2-approximation算法,证明:
设该问题的最优解为V*,假设我们把问题的W给为W’=前k+1个物品的重量和,那么在新的问题下将会是最优解,这是因为首先选择的物品均是性价比最高的,而且正好充满了背包。因为我们将背包size调大,那么新问题的最优解肯定大于等于原问题的最优解,即,V*<=前k+1个物品的价值和。又S1+S2=前k+1个物品的价值和,所以V>=一半的(前k+1个物品的价值和),(因为两个数中的较大者肯定不小于其和的一半)。所以我们可以得到V*<=2V,得证。
DP解法: