背包问题
instance:给定n个item, i=1,2,…,n ; weights w1,w2,…,wn∈Z+ ; values v1,v2,…,vn∈Z+ , 给定背包容量 B∈Z+ ;
需要找到一个集合 S∈{1,2,…,n} 让背包里面的东西value最大。
1.贪心算法
根据 viwi 的大小排序,每次放进去性价比高的item,直到不能放为止。
2.动态规划
定义:
A(i,v) 代表从 s∈{1,2,…,i} 里找到价值为v的最小的w和;如果这个集合s找不到,那么 +∞ .
显然我们有:
A(i,v)=min{A(i−1,v),A(i−1,v−vi)+wi}
接下来我们就可以填表格似的求出max v such that A(n,v)≤B .
接下来分析这个算法,这个算法需要填的表的大小是 n×V ,其中 V=∑ni=1vi ,因此这个算法时间复杂度是 O(n×V) .
问题的规模是n的,V不是n的多项式,所以这个算法不是polynomial time的。这个是伪多项式时间的算法。
3.fptas(Fully Polynomial-Time Approximation Scheme)
完全多项式时间近似方案。就是无论多小的 ϵ ,都能够找到一个多项式时间的算法使得它的approximation ratio >1−ϵ ,(或者小于1+)。
对于这个背包问题,我们可以观察到伪多项式算法只是由于V不是多项式的,因此可以把V化成n的多项式相关的,令:
v̂ i=⌊viK⌋
然后利用动态规划算法,求出这个新 v̂ 集合的收益最大的集合 Ŝ . 假设opt最优的集合为 O
显然有:
so:
K×∑i∈Ŝ v̂ i≥K×∑i∈Ov̂ i
又有:
⌊viK⌋>viK−1
So:
K×v̂ i>vi−K
So:
K×∑i∈Ov̂ i=∑i∈OK×v̂ i≥∑i∈O(vi−K)≥opt−nK
if we want:
solopt>1−ϵ
then we want:
opt−nKopt≥1−ϵ
then:
n×Kopt≤ϵ
我们只需要找到opt的最小值即可。
那么opt显然是大于能放进这个背包中的物体中最大的那一个价值的。
记为P
Then:
K=ϵ×Pn
分析一下它的时间复杂度:
∑i∈Sv̂ i=∑i∈S⌊vi/K⌋<⌊∑i∈Svi/k⌋
And:
∑i∈Svi/P<n
Then:
v̂ <n×nϵ
因此时间复杂度为: O(n3/ϵ)