Approximation Algorithm for NP-Complete Problems
- 启发式算法:非常快速但不是百分之一百准确的算法——近似最优算法
- 针对背包问题
- 可计算的特例? W W W很小时或者为 n n n的多项式关系时计算可行
- 比暴力搜索相对好的算法? O ( n W ) O(nW) O(nW)的动态规划,比 O ( 2 n ) O(2^n) O(2n)的暴力搜索要好很多
- 针对背包问题的贪心启发式算法
- 按照 v i w i \frac {v_i}{w_i} wivi降序排序,按顺序逐个尝试放入背包,直到装不下任何新目标
- 附加步骤:最后要么返回上述结果,要么返回最大价值(比最优解好)的物品价值
- 第二个选择能够保证达到至少50%的最优解
- 时间复杂度 O ( n log n ) O(n \log n) O(nlogn)
- 更好一点?
- 更强的假设:每一个物体的体积都在总体积的10%以内
- 无附加贪心算法:能够保证达到至少90%的最优解
- 同理,如果保证 max w i ≤ δ W \max w_i \le \delta W maxwi≤δW,则无附加贪心算法能够保证达到 ( 1 − δ ) (1 - \delta) (1−δ)的最优解
- 更强的假设:每一个物体的体积都在总体积的10%以内
- 针对背包问题的dp启发式算法
- 已知
- 如果 w i w_i wi和 W W W足够小且为整数,那么可以争取一个 O ( n W ) O(nW) O(nW)的动态规划算法
- 如果 v i v_i vi足够小且为整数,那么可以实现一个多项式时间算法
- 思路:“不那么正确”,不限制 v i v_i vi的大小,但是将其转化为较小的情形,从而多项式时间解决——放弃低阶位
- 算法
- 由误差 ϵ \epsilon ϵ确定一个基数 m m m,将所有的 v i v_i vi向下舍入到最近的 m m m的倍数(越大的 m m m,舍去的信息越多,准确率越低),将舍入后的 v i v_i vi除以 m m m得到整数表示 v ^ i = ⌊ v i m ⌋ \hat v_i = \lfloor \frac {v_i}{m} \rfloor v^i=⌊mvi⌋
- 在转换后的 v ^ i \hat v_i v^i上使用dp算法计算最优解—— O ( n 2 × max i v ^ i ) O(n^2 \times \max_i \hat v_i) O(n2×maxiv^i)
- 小整数算法子结构:考虑物品与各个价值单位上可能的选择
- S i , x S_{i, x} Si,x:当背包内物品价值至少为 x x x时,使用前 i i i个物品所能达到的最小体积占用
- i i i循环从1到 n n n; x x x循环从0到 n × max v i n \times \max v_i n×maxvi
- S i , x = min { S i − 1 , x , w i + S i − 1 , x − v i } S_{i, x} = \min \{S_{i - 1, x}, w_i + S_{i - 1, x - v_i}\} Si,x=min{Si−1,x,wi+Si−1,x−vi}
- 当 v i ≥ x v_i \ge x vi≥x时,直接置0
- 小整数算法实现
- 初始化: A [ 0 , 0 ] = 0 , A [ 0 , x ] = + ∞ A[0, 0] = 0, A[0, x] = +\infty A[0,0]=0,A[0,x]=+∞
- 主循环:
i
=
1
…
,
n
i = 1 \dots, n
i=1…,n
- 副循环:
x
=
0
,
…
,
n
v
m
a
x
x = 0, \dots, n v_{max}
x=0,…,nvmax
- A [ i , x ] = min { A [ i − 1 , x ] , w i + A [ i − 1 , x − v i ] } A[i, x] = \min \{A[i - 1, x], w_i + A[i - 1, x-v_i]\} A[i,x]=min{A[i−1,x],wi+A[i−1,x−vi]}
- 副循环:
x
=
0
,
…
,
n
v
m
a
x
x = 0, \dots, n v_{max}
x=0,…,nvmax
- 从最大的 x x x到最小,寻找最大的满足 A [ n , x ] ≤ W A[n, x] \le W A[n,x]≤W的 x x x即为所求
- 时间复杂度: O ( n 2 v m a x ) O(n^2 v_{max}) O(n2vmax)
- m m m的确定 m = ϵ v m a x n m = \epsilon \frac {v_{max}}{n} m=ϵnvmax
- 足够小的 m m m,因此算法时间复杂度 O ( 1 ϵ n 3 ) O(\frac 1\epsilon n^3) O(ϵ1n3)
- 已知