算法设计与分析6_近似算法
苏大(suda)——算法设计与分析
多级调度问题
如果我们不排序,直接按。。。。,则可以得到2xx近似算法。
近似算法
优化问题
装箱问题
每个NP完全优化问题,都有一个判定问题的版本
近似算法都不是指数时间,一定是多项式时间。
总之就是拿精度,换时间。
近似算法的性能
即,性能保证。就是衡量近似算法的最优解和近似解之间的差别。
绝对性能保证
“绝对性能保证”是指在任何情况下,无论外部环境如何变化,系统或设备都能够始终如一地达到或超过预期的最高性能水平。
“绝对性能保证”是一个很强的承诺,在实际工程和商业环境中非常罕见,甚至可以说是不存在的。
由于“绝对性能保证”强调的是在所有情况下都能达到或超过预期最高性能水平,我们可以尝试用以下公式来表达:
其中:
- ∀:表示“对于所有”。
- e:代表所有可能的外部环境因素的集合 E 中的一个元素。E 可以包含各种因素,例如用户数量、网络状况、硬件配置等等。
- s:代表系统或设备。
- P( s, e ):表示在外部环境 e 下,系统 s 的实际性能。
- Pmax:表示系统 s 的理论最大性能或预期最高性能。
即,对于所有可能的外部环境 e,系统 s 的实际性能 P( s, e ) 必须大于等于其理论最大性能 Pmax。
对于绝大所数的优化问题,除非p=np,否则不存在绝对近似算法。
01背包问题
对于绝大所数的优化问题,除非p=np,否则不存在绝对近似算法。
s表达大小,p表示价值
图片展示的是一个关于背包问题的定理及其证明过程。这个定理阐述了在P≠NP的假设下,背包问题不存在具有特定性能保证的近似算法。下面我用 Markdown 格式复述图片内容:
定理(Theorem 6):
若 P≠NP,则对于任何确定的 k,找不到近似算法 A 可解背包问题,使得: \(| A( I ) - OPT( I ) | ≤ k\)
其中:
- A( I ):算法 A 在输入实例 I 上的解。
- OPT( I ):输入实例 I 的最优解。
- k:一个确定的常数。
证明(Proof):
使用扩放法(Scaling)进行反证。
-
假设存在算法 A 具有性能保证 k(注意 k 是正整数)。
-
设 ∀ I ∈ D(任意输入实例 I),可构造新实例 I',使得:
- si' = si (大小不变)
- pi' = (k + 1)pi, for i ∈ [1, n] (利润缩放)
即:除了利润扩放 k + 1 倍之外,其余参数不变。故 I 的可行解也是 I' 的可行解,反之亦然。只是解的值相差 k + 1 倍。
-
在 I' 上运行算法 A 获得解 A( I' ),设 A 在实例 I 上的解是:
| A( I' ) - OPT( I' ) | ≤ k
| (k + 1)f(σ) - (k + 1)OPT( I ) | ≤ k
(这里 f(σ) 似乎代表一个解的函数,但图片中不够清晰。)
-
(图片中最后一句不太完整,推测其含义是:)
即:我们已经找到了一个多项式时间的算法 A,它对背包问题的任一输入实例 I,均能找到最优解。
证明逻辑分析:
该证明使用反证法。它首先假设存在一个具有性能保证 k 的近似算法 A。然后通过对输入实例进行缩放(scaling),构造一个新的实例 I',使得利润值扩大 k + 1 倍。如果原算法 A 在 I' 上仍然满足性能保证 k,那么通过简单的推导,可以得出 A 在原实例 I 上也能找到最优解。这意味着背包问题存在多项式时间的最优解算法,从而导致 P=NP,这与定理的前提 P≠NP 相矛盾。因此,原假设不成立,即不存在具有性能保证 k 的近似算法。
总结:
图片内容证明了在 P≠NP 的前提下,背包问题不存在具有固定性能比的近似算法。这意味着,如果我们坚持要找到最优解,那么我们可能需要付出指数级的时间复杂度。这也解释了为什么在实际应用中,人们通常会使用一些启发式算法或近似算法来寻找次优解,以在可接受的时间内获得相对较好的结果。
希望以上复述对您有所帮助。如果图片中还有其他信息我没有捕捉到,请指出。
常常用贪心的思想设计算法。
approximation ratio
近似比很重要=性能保证,但是近似比不一定可求。
最佳算法要trade-off 近似比和效率。
近似比\(r(A)=sup \frac{A(I)}{opt(I)}\) 一定大于1,等于1就不是近似算法。
- 备注:sup是supremum的意思,表示上确界. sup代表一个集合中的最小最大值
0-1背包贪心算法🌟
2近似算法。
关键:根据\(\frac{v_i}{w_i}\)排序。
图片展示的是一种解决 0-1 背包问题的贪心算法的内容,主要包括以下几点:
-
输入:给定正整数 \(S\),以及物品的重量 \(w_1, w_2, \ldots, w_n\) 和价值 \(v_1, v_2, \ldots, v_n\)。
-
步骤:
- 根据物品的单位价值 \(\frac{v_i}{w_i}\) 的大小,对所有物品按从大到小排序。
- 假设排序结果为 \(\frac{v_1}{w_1} \geq \frac{v_2}{w_2} \geq \ldots \geq \frac{v_n}{w_n}\)。
- 检查:
- 如果前 \(k\) 个物品的总重量 \(\sum_{i=1}^k w_i \leq S\),则输出总价值 \(C_G = \sum_{i=1}^k v_i\)。
- 否则,找到最大 \(k\),使得 \(\sum_{i=1}^k w_i \leq S \leq \sum_{i=1}^{k+1} w_i\)。
-
输出:最终的最大总价值 \(C_G = \max \{ v_{k+1}, \sum_{i=1}^k v_i \}\)。
GreedyKnapsack01(weights, values, W):
1. n ← length(weights) // 物品数量
2. Create an array items with tuples (value, weight, value/weight)
3. Sort items by value/weight in descending order
4. totalValue ← 0
5. for each item in items:
6. if item.weight ≤ W:
totalValue ← totalValue + item.value
W ← W - item.weight
7. return totalValue
如何证明二近似?
第一部分:问题描述
假设最优解 \(OPT\) 是某些物品集合的价值总和,其对应的总重量不超过背包容量 \(S\)。贪心算法的核心是基于单位价值 \(\frac{v_i}{w_i}\) 的递减排序,逐步尝试填满背包。
第二部分:关键步骤和性质
-
假设和目标:
- 设贪心算法将物品按单位价值排序,选取的前 \(k+1\) 个物品中,总重量第一次超过背包容量 \(S\)。
- 贪心算法的输出价值 \(C_G\) 为:
\( C_G = \max\left\{ \sum_{i=1}^k v_i, v_{k+1} \right\} \)
-
上界分析:
- 根据贪心算法的选择规则,单位价值 \(\frac{v_{k+1}}{w_{k+1}}\) 是最小的,因此最优解 \(OPT\) 的价值总和也受此约束。
-
表示最优解:
- 假设背包装满时达到总重量 \(S\),最优解 \(OPT\) 的上界即为 分数背包 可以表示为:
\(OPT \leq \sum_{i=1}^k v_i + \left(S - \sum_{i=1}^k w_i \right) \cdot \frac{v_{k+1}}{w_{k+1}}\) - 通过缩放可得:
\(OPT \leq \sum_{i=1}^k v_i + \left(S - \sum_{i=1}^k w_i \right) \cdot \frac{v_{k+1}}{w_{k+1}} \leq \sum_{i=1}^{k+1} v_i\)
- 假设背包装满时达到总重量 \(S\),最优解 \(OPT\) 的上界即为 分数背包 可以表示为:
第三部分:近似度证明
- 贪心算法的输出是两部分中的较大值:
\( C_G = \max\left\{ \sum_{i=1}^k v_i, v_{k+1} \right\} \) - 易得 \(C_G \geq \sum_{i=1}^{k+1} v_i\)
- 那么
\(C_G \geq \frac{1}{2} \left(\sum_{i=1}^k v_i + v_{k+1}\right)\)
因此,贪心算法的结果满足 \(C_G \geq \frac{OPT}{2}\),证明该算法是二近似算法。
其他题:最小时间跨度问题
最小时间跨度排序
给定几个job,处理时间P1,2,..;P你、以及整数m
找到一种把job分给m个同型机machine分配方式,使得完工时间跨度最小、
经典的NP-hardi问题(NPC)
PTAS 多项式时间应似方案 归约到受限装箱问题
2近似算法步骤:
- STEP1:按照job放入队列
- STEP2:将job分配给当前为止工作压力最小的machine
优化目标 / 如何证明2近似
近似方案
和常数近似的区别就是 近似方案和\(ε\)的设置有关。
近似方案的定义 Detinion of aproximation Scheme
近似方案(Approximation Scheme)
设是目标函数为f的NP-hard最优化问题,如果关于输入(1,E),1为的 实例,为误差参数,算法A输出解S使得
-
若是最小化问题,f(I,S) ≤ (1 + ε)· OPT
目标函数在输入为I的实例下输出解S小于(1+) · OPT -
若是最大化问题,f(I,S) ≥ (1 – ε)· OPT
我们称算法A是NP-Hard优化问题的近似方案
PTAS 和 FPTAS 的定义
PTAS (Polynomial-Time Approximation Scheme)
■ 若对于每一个固定的\(ɛ>0\),算法A的运行时间以实例的规模的多项式为上界,则A是一个多项式时间近似方案(简称PTAS)。
FPTAS (Fully Polynomial-Time Approximation Scheme)
■ 在PTAS的基础上,我们进一步要求算法A,即算法A的运行时间以实例的规模和\(\frac{1}{ɛ}\)的多项式为上界,则称A是一个完全多项式时间近似方案(简称FPTAS)。
FPTAS被认为是最值得研究的近似算法,仅有极少的NP-hard问题存在FPTAS
理解:
对于算法 \(O(n^{\frac{1}{ɛ}})\)
对于PTAS, 如果ɛ=0.1 则是\(O(n^{10})\) ,如果ɛ=0.001 则是\(O(n^{1000})\)
对于FPTAS算法,则有\(O(\frac{1}{ɛ} n^2)\)这种形式,很明显效率变小了。
0-1背包的伪多项式时间算法
通过DP设计近似算法。
■问题
给定物品集合S = (a1,..., a},每个物品有指定的大小size(a₁)∈Z+和指定的收益 profit(a) ∈ Z+,以及背包容量B∈Z+,找一个子集,该子集的总大小以B为上界 并且它的总收益最大。
■算法思路
定义P是收益最大的物品的收益,\(P = max profit(a)\).
则\(nP\)是任何解能够获得的收益的一个平凡上界。
对于每个\(i∈ \{1, ..., n\}\)和 \(p∈ \{1, ..., nP\}\),
设\(S_{i,p}\)表示\(\{a₁,...,a_i\}\)的一个子集,该子集的总收益正好是p,并且它的总大小Size达到最小。
原始的DP是把容量卡死,将收益最大。
设\(A(i,p)\)表示集合 \(S_{i,p}\) 的大小(如 果这样的集合不存在,则\(A(i,p) = ∞)\)。显然,对于每一个\(p∈ \{0,1,..., nP\}\), A(1,p) 是已知的(递归的终止条件)
设计思路
精确度换取时间
若各物品收益均是比较小的数,即它们以內的多项式为上界,那么基于上述递推式所设计的 DP算法是一个常规的多项式时间算法,因为它的运算时间以川的多项式为上界,但是,当P 是指数级,就需要对物品价值进行放缩,即
忽略各物品价值的最后若干有效位(依赖于误差参数)
以便将修改后的收益看作是以和1/的多项式为上界的数。
所以,我们可以在以和1/的多项式为上界的时间内找到收益至少为(1-8)·OPT 的解。
考试:0-1背包问题的FPTAS
(实现方法-- 缩放和取整)
STEP1:给定\(ɛ > 0\),设\(K=\frac{ɛP}{n}\)
- ɛ误差参数,n物品数量,P最大物品价值
STEP2:对每个物品\(a_i\),定义\(profit'(a_i) = \vert \frac{profit(a_i)}{K} \vert\).
- 截断小数部分 --》算法变高效
STEP3:用这些值作为物品新的收益(价值),利用前述动态规划算法找到收益最大的集合,记为\(S'\).
- 即 0-1背包的伪多项式时间算法
STEP4:输出\(S'\)
伪代码🌟
#f(i,v) 表示从前i件中挑选出使得价值为v,并且是size最小, 如果找不到就无穷大
#V = max(v)
#复杂度为(n**2 * V)
c 背包总容量
# values 价值 , weights 重量 ɛ 误差参数
FPTAS_KP(values, weights, ɛ )
P = max(values)
K = (ɛ*P)/n
newValues = ⌊ values / K ⌋
newP = max(newValues)
target = 0
dp = ∞
dp[0][ newValues[0] ] = weights[0]
for i in range(1,n):
dp[i -1][ newValues[i] ] =min (dp[i-1][newValues[i], weights[i])
for j in range( n * newP ):
if j - newValues[i] >= 0:
dp[i][j] = min(dp[i-1][j], dp[i-1][ j-newValues[i] ] + weights[i])
else:
dp[i][j] = dp[i-1][j]
if dp[i][j] <= c:
target = j
total = dp[ c ][ target ]
return total
证明是FPTAS
需要证明两点
- f (1-ɛ)-OPT
- n,1\ɛ多项式为上界