算法设计与分析6_近似算法

苏大(suda)——算法设计与分析

多级调度问题

image

如果我们不排序,直接按。。。。,则可以得到2xx近似算法。

近似算法

优化问题

image

装箱问题

每个NP完全优化问题,都有一个判定问题的版本

近似算法都不是指数时间,一定是多项式时间。
总之就是拿精度,换时间。

近似算法的性能
即,性能保证。就是衡量近似算法的最优解和近似解之间的差别。

绝对性能保证

“绝对性能保证”是指在任何情况下,无论外部环境如何变化,系统或设备都能够始终如一地达到或超过预期的最高性能水平。
“绝对性能保证”是一个很强的承诺,在实际工程和商业环境中非常罕见,甚至可以说是不存在的

由于“绝对性能保证”强调的是在所有情况下都能达到或超过预期最高性能水平,我们可以尝试用以下公式来表达:

\[∀ e ∈ E, P( s, e ) ≥ P_{max} \]

其中:

  • ∀:表示“对于所有”。
  • e:代表所有可能的外部环境因素的集合 E 中的一个元素。E 可以包含各种因素,例如用户数量、网络状况、硬件配置等等。
  • s:代表系统或设备。
  • P( s, e ):表示在外部环境 e 下,系统 s 的实际性能。
  • Pmax:表示系统 s 的理论最大性能或预期最高性能。

即,对于所有可能的外部环境 e,系统 s 的实际性能 P( s, e ) 必须大于等于其理论最大性能 Pmax

对于绝大所数的优化问题,除非p=np,否则不存在绝对近似算法。

01背包问题

对于绝大所数的优化问题,除非p=np,否则不存在绝对近似算法。

s表达大小,p表示价值

image
图片展示的是一个关于背包问题的定理及其证明过程。这个定理阐述了在P≠NP的假设下,背包问题不存在具有特定性能保证的近似算法。下面我用 Markdown 格式复述图片内容:

定理(Theorem 6):

若 P≠NP,则对于任何确定的 k,找不到近似算法 A 可解背包问题,使得: \(| A( I ) - OPT( I ) | ≤ k\)

其中:

  • A( I ):算法 A 在输入实例 I 上的解。
  • OPT( I ):输入实例 I 的最优解。
  • k:一个确定的常数。

证明(Proof):

使用扩放法(Scaling)进行反证。

  1. 假设存在算法 A 具有性能保证 k(注意 k 是正整数)。

  2. 设 ∀ ID(任意输入实例 I),可构造新实例 I',使得:

    • si' = si (大小不变)
    • pi' = (k + 1)pi, for i ∈ [1, n] (利润缩放)

    即:除了利润扩放 k + 1 倍之外,其余参数不变。故 I 的可行解也是 I' 的可行解,反之亦然。只是解的值相差 k + 1 倍。

  3. I' 上运行算法 A 获得解 A( I' ),设 A 在实例 I 上的解是:

    | A( I' ) - OPT( I' ) | ≤ k

    | (k + 1)f(σ) - (k + 1)OPT( I ) | ≤ k

    (这里 f(σ) 似乎代表一个解的函数,但图片中不够清晰。)

  4. (图片中最后一句不太完整,推测其含义是:)

    即:我们已经找到了一个多项式时间的算法 A,它对背包问题的任一输入实例 I,均能找到最优解。

证明逻辑分析:

该证明使用反证法。它首先假设存在一个具有性能保证 k 的近似算法 A。然后通过对输入实例进行缩放(scaling),构造一个新的实例 I',使得利润值扩大 k + 1 倍。如果原算法 AI' 上仍然满足性能保证 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 背包问题的贪心算法的内容,主要包括以下几点:

  1. 输入:给定正整数 \(S\),以及物品的重量 \(w_1, w_2, \ldots, w_n\) 和价值 \(v_1, v_2, \ldots, v_n\)

  2. 步骤

    • 根据物品的单位价值 \(\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\)
  3. 输出:最终的最大总价值 \(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}\) 的递减排序,逐步尝试填满背包。

第二部分:关键步骤和性质

  1. 假设和目标:

    • 设贪心算法将物品按单位价值排序,选取的前 \(k+1\) 个物品中,总重量第一次超过背包容量 \(S\)
    • 贪心算法的输出价值 \(C_G\) 为:
      \( C_G = \max\left\{ \sum_{i=1}^k v_i, v_{k+1} \right\} \)
  2. 上界分析:

    • 根据贪心算法的选择规则,单位价值 \(\frac{v_{k+1}}{w_{k+1}}\) 是最小的,因此最优解 \(OPT\) 的价值总和也受此约束。
  3. 表示最优解:

    • 假设背包装满时达到总重量 \(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\)

第三部分:近似度证明

  • 贪心算法的输出是两部分中的较大值:
    \( 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近似算法步骤:

  1. STEP1:按照job放入队列
  2. STEP2:将job分配给当前为止工作压力最小的machine

优化目标 / 如何证明2近似
image

近似方案

和常数近似的区别就是 近似方案和\(ε\)的设置有关。

近似方案的定义 Detinion of aproximation Scheme

近似方案(Approximation Scheme)

设是目标函数为f的NP-hard最优化问题,如果关于输入(1,E),1为的 实例,为误差参数,算法A输出解S使得

  1. 若是最小化问题,f(I,S) ≤ (1 + ε)· OPT
    目标函数在输入为I的实例下输出解S小于(1+) · OPT

  2. 若是最大化问题,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\ɛ多项式为上界
posted @ 2025-01-06 09:42  kingwzun  阅读(171)  评论(0)    收藏  举报