0


算法导论习题—摊还时间代价分析、栈实现队列、贪心算法近似比、集合覆盖问题

在这里插入图片描述

在执行的

  1. n
  2. n
  3. n个操作中,有至多
  4. l
  5. g
  6. n
  7. lg n
  8. lgn⌉个操作的次序是
  9. 2
  10. 2
  11. 2的幂,这些操作的次序(即代价)如下
  12. 1
  13. ,
  14. 2
  15. ,
  16. 4
  17. ,
  18. 8
  19. ,
  20. ,
  21. 2
  22. l
  23. g
  24. n
  25. 1, 2, 4, 8, · · · , 2 lg n
  26. 1,2,4,8,⋅⋅⋅,2lgn
  27. n
  28. n
  29. n个操作的总代价为
  30. T
  31. =
  32. k
  33. =
  34. 0
  35. l
  36. g
  37. n
  38. 2
  39. k
  40. +
  41. (
  42. n
  43. l
  44. g
  45. n
  46. )
  47. ×
  48. 1
  49. =
  50. 2
  51. l
  52. g
  53. n
  54. +
  55. 1
  56. 1
  57. +
  58. (
  59. n
  60. l
  61. g
  62. n
  63. )
  64. 2
  65. lg
  66. n
  67. +
  68. 2
  69. +
  70. n
  71. l
  72. g
  73. n
  74. =
  75. 3
  76. l
  77. g
  78. n
  79. +
  80. n
  81. \begin{aligned} T&=\sum^{⌈lg n⌉}_{k=0}2^k + (n lg n⌉) × 1\\ &=2^{⌈lg n⌉+1} 1 + (n lg n⌉)\\ &≤2^{\lg n+2} + n lg n\\ &=3 lg n + n \end{aligned}
  82. T​=k=0∑⌈lgn⌉​2k+(n−⌈lgn⌉)×1=2lgn⌉+11+(n−⌈lgn⌉)≤2lgn+2+nlgn=3lgn+n

因此每个操作的摊还代价是

  1. O
  2. (
  3. 3
  4. lg
  5. n
  6. +
  7. n
  8. n
  9. )
  10. =
  11. O
  12. (
  13. 1
  14. )
  15. O ( \cfrac{3 \lg n + n }n ) = O(1)
  16. O(n3lgn+n​)=O(1)的。

在这里插入图片描述

当操作次序是

  1. 2
  2. 2
  3. 2的幂时,为其赋
  4. 4
  5. 4
  6. 4的摊还代价,否则为其赋
  7. 2
  8. 2
  9. 2的摊还代价,则每一个不为
  10. 2
  11. 2
  12. 2 的幂的操作均会提供
  13. 1
  14. 1
  15. 1的信用以支付差额,对于一
  16. n
  17. n
  18. n个操作组成的操作序列,有
  19. 4
  20. ×
  21. lg
  22. n
  23. +
  24. 2
  25. ×
  26. (
  27. n
  28. lg
  29. n
  30. )
  31. =
  32. 2
  33. ×
  34. lg
  35. n
  36. +
  37. 2
  38. n
  39. 3
  40. lg
  41. n
  42. +
  43. n
  44. k
  45. =
  46. 0
  47. l
  48. g
  49. n
  50. 2
  51. k
  52. +
  53. (
  54. n
  55. lg
  56. n
  57. )
  58. ×
  59. 1
  60. \begin{aligned} &4×⌈\lg n⌉+2×(n−⌈\lg n⌉) \\ &=2×⌈\lg n⌉+2n\\ &≤3\lg n+n\\ &≤\sum^{⌈lg n⌉}_{k=0}2^k+(n−⌈\lg n⌉)×1 \end{aligned}
  61. 4×⌈lgn⌉+2×(n−⌈lgn⌉)=2×⌈lgn⌉+2n3lgn+nk=0∑⌈lgn⌉​2k+(n−⌈lgn⌉)×1

每个操作的摊还代价都是常数,因此摊还代价都为

  1. O
  2. (
  3. 1
  4. )
  5. O(1)
  6. O(1)。

在这里插入图片描述

定义势函数

  1. Φ
  2. P
  3. h
  4. i
  5. (
  6. D
  7. i
  8. )
  9. =
  10. {
  11. 0
  12. ,
  13. i
  14. =
  15. 0
  16. 1
  17. ,
  18. i
  19. =
  20. 1
  21. lg
  22. i
  23. +
  24. 1
  25. ,
  26. i
  27. =
  28. 2
  29. lg
  30. i
  31. lg
  32. i
  33. +
  34. k
  35. ,
  36. i
  37. =
  38. 2
  39. lg
  40. i
  41. +
  42. k
  43. ΦPhi(D_i) =\left\{ \begin{aligned} & 0, \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ i = 0\\ &1, \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ i = 1\\ & \lg i + 1, \ \ \ \ \ \ \ \ \ \ \ \ \ \ i = 2^{⌊\lg i⌋}\\ & \lg i + k, \ \ \ \ \ \ \ \ \ \ i = 2^{⌊\lg i⌋} + k \end{aligned} \right.
  44. ΦPhi(Di​)=⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧​​0, i=01, i=1lgi+1, i=2lgi⌋⌊lgi⌋+k, i=2lgi⌋+k

则对任意的

  1. i
  2. Φ
  3. (
  4. D
  5. i
  6. )
  7. 0
  8. i,Φ(D_i) 0
  9. i,Φ(Di​)≥0,且
  10. Φ
  11. (
  12. D
  13. i
  14. )
  15. Φ
  16. (
  17. D
  18. i
  19. 1
  20. )
  21. =
  22. {
  23. 1
  24. i
  25. ,
  26. i
  27. =
  28. 2
  29. lg
  30. i
  31. 1
  32. ,
  33. i
  34. =
  35. 2
  36. lg
  37. i
  38. +
  39. k
  40. Φ(D_i) Φ(D_{i1}) =\left\{ \begin{aligned} & 1-i, \ \ \ \ \ \ \ \ i = 2^{⌊\lg i⌋}\\ & 1, \ \ \ \ \ \ \ \ \ \ \ \ \ \ i = 2^{⌊\lg i⌋} + k \end{aligned} \right.
  41. Φ(Di​)−Φ(Di1​)={​1i, i=2lgi1, i=2lgi⌋+k

所以:

  1. i
  2. =
  3. 1
  4. n
  5. c
  6. ^
  7. =
  8. i
  9. =
  10. 1
  11. n
  12. 1
  13. =
  14. n
  15. \sum^n_{i=1}\hat{c}=\sum^n_{i=1}1=n
  16. i=1nc^=i=1n1=n

因此每个操作的摊还代价是

  1. O
  2. (
  3. 1
  4. )
  5. O(1)
  6. O(1)。

在这里插入图片描述

使用两个栈实现队列,将两个栈记为左右栈。

  1. ENQUEUE
  2. \text{ENQUEUE}
  3. ENQUEUE:直接对左栈进行
  4. push
  5. \text{push}
  6. push将元素入队
  7. DEQUEUE
  8. \text{DEQUEUE}
  9. DEQUEUE:如果右栈非空,对右栈进行
  10. pop
  11. \text{pop}
  12. pop。如果右栈为空,做一个迭代:把左栈元素
  13. pop
  14. \text{pop}
  15. pop出来,
  16. push
  17. \text{push}
  18. push进右栈,直到左栈为空,再执行
  19. DEQUEUE
  20. \text{DEQUEUE}
  21. DEQUEUE
  22. FIND-MIN
  23. \text{FIND-MIN}
  24. FIND-MIN:在左右栈基础上再加一个辅助栈,用于记录最小值。每次有元素入左栈时,判断辅助栈为空或辅助栈的栈顶元素比入栈元素更大,则将该元素压入辅助栈中,否则将辅助栈的栈顶元素重复压入辅助栈。左栈需要弹出元素时,辅助栈需要同步弹出栈顶元素。取最小值时,直接将栈顶元素弹出,返回值即最小值。

摊还分析:

  1. C
  2. i
  3. C_i
  4. Ci​为第
  5. i
  6. i
  7. i个操作的代价(假定每个操作的代价为
  8. 1
  9. 1
  10. 1)设每次操作的势能
  11. D(i)=2*
  12. \text{D(i)=2*}
  13. D(i)=2*左栈元素个数,设左栈元素个数为
  14. k
  15. k
  16. k
  17. ENQUEUECi+D(i)-D(i-1)=1+2*(k+1-k)=3
  18. \text{ENQUEUECi+D(i)-D(i-1)=1+2*(k+1-k)=3}
  19. ENQUEUECi+D(i)-D(i-1)=1+2*(k+1-k)=3
  20. k
  21. +
  22. 1
  23. k+1
  24. k+1表示入队后的元素,所以入队摊还时间复杂度为
  25. O
  26. (
  27. 1
  28. )
  29. O(1)
  30. O(1)
  31. DEQUEUE
  32. \text{DEQUEUE}
  33. DEQUEUE
  1. 如果右栈非空,左栈有 k k k个元素: Ci+D(i)-D(i-1)=1+2(k-k)=1 \text{Ci+D(i)-D(i-1)=1+2(k-k)=1} Ci+D(i)-D(i-1)=1+2(k-k)=1

  2. 如果右栈为空,左栈有 k k k个元素: Ci+D(i)-D(i-1)=2k+1+2(0-k)=1 \text{Ci+D(i)-D(i-1)=2k+1+2(0-k)=1} Ci+D(i)-D(i-1)=2k+1+2(0-k)=1,其中 2 k 2k 2k为左栈弹出元素数+右栈压入元素数, 1 1 1表示出队一个元素,所以出队摊还时间复杂度为 O ( 1 ) O(1) O(1)

    1. FIND-MIN
    2. \text{FIND-MIN}

    FIND-MIN: 使用聚合法分析,取最小值实际上是对单个辅助栈的操作,考虑整个栈的

    1. n
    2. n

    n个操作,一个对象压入栈后,至多弹出一次,则对该栈的

    1. n
    2. n

    n个

    1. PUSHPOPMULTIPOP
    2. \text{PUSHPOPMULTIPOP}

    PUSH、POP、MULTIPOP的操作序列,代价至多是

    1. O
    2. (
    3. n
    4. )
    5. O(n)

    O(n),一个操作的平均时间为

    1. O
    2. (
    3. n
    4. )
    5. /
    6. n
    7. =
    8. 1
    9. O(n)/n=1

    O(n)/n=1,所以摊还复杂度为

    1. O
    2. (
    3. 1
    4. )
    5. O(1)

    O(1)。

在这里插入图片描述

每次迭代添加包含未覆盖元素最多的集合, 直到满足全覆盖条件,时间复杂度为多项式时间

  1. Θ
  2. (
  3. k
  4. lg
  5. n
  6. )
  7. \Theta(k\lg n)
  8. Θ(klgn)

假设全集

  1. S
  2. S
  3. S包含
  4. n
  5. n
  6. n个元素,最优覆盖包含
  7. k
  8. k
  9. k个子集合。那么我们使用的贪心算法最多会选择
  10. k
  11. ln
  12. n
  13. +
  14. 1
  15. k\ln n+1
  16. klnn+1个子集。

证明:

    1. u j u_j uj​:在贪心算法第 j j j次迭代还没有被覆盖的元素个数
    1. O P T OPT OPT:最优解
    1. k k k个最优集合必定可覆盖住该 u j u_j uj​个元素,故最优集合中至少有一个集合包含至少 u j k \cfrac{u_j}k kuj​​个元素
  1. 使用贪心算法后,我们可以递推得到 u j + 1 ≤ u j − u j k = u j ( 1 − 1 k ) ≤ u j − 1 ( 1 − 1 k ) ( 1 − 1 k ) ≤ … ≤ u 0 ( 1 − 1 k ) j + 1 = n ( 1 − 1 k ) j + 1 u_{j+1}\le u_j-\frac{u_j}k = u_j(1-\frac{1}k)\le u_{j-1}(1-\frac{1}k)(1-\frac{1}k)\le…\le u_0(1-\frac{1}k)^{j+1}=n(1-\frac{1}k)^{j+1} uj+1​≤uj​−kuj​​=uj​(1−k1​)≤uj−1​(1−k1​)(1−k1​)≤…≤u0​(1−k1​)j+1=n(1−k1​)j+1 所以 u j + 1 ≤ n ( 1 − 1 k ) j + 1 u_{j+1}\le n(1-\frac{1}k)^{j+1} uj+1​≤n(1−k1​)j+1
    1. lim x + ( 1 + x n ) n = e x \displaystyle\lim_{x \rightarrow + \infty}(1 + \frac{x}{n})^n = e^x x→+∞lim​(1+nx​)n=ex,即存在这样一个式子 1 x < = e x 1-x <= e^{-x} 1x<=ex对所有的 x x x都成立 所以 u j u 0 ( 1 1 k ) j < u 0 ( e 1 k ) j = n e j k ( 1 1 k ) j = ( ( 1 1 k ) k ) j k e j k n e j k 1 e j k n 1 j k ln n j k ln n \begin{aligned} &u_j \le u_0(1-\frac{1}k)^j < u_0(e^{-{\frac{1}k}})^j = ne^{-{\frac{j}k}}\\ &(1-\frac{1}k)^j=((1-\frac{1}k)^k)^\frac{j}k\le e^{-\frac{j}k}\\ &n·e^{-\frac{j}k}\le 1\Leftrightarrow e^{-\frac{j}k}\le n^{-1}\Leftrightarrow -\frac{j}k \le-\ln n\Leftrightarrow j\ge k\ln n \end{aligned} uj​≤u0​(1k1​)j<u0​(ek1​)j=nekj​(1k1​)j=((1k1​)k)kj​≤ekjnekj​≤1ekj​≤n1⇔−kj​≤−lnnjklnn j = k ln n j=k\ln n j=klnn,结果等于 1 1 1,也就是说没有其他的元素剩下了,此时 ( 1 1 k ) k ln n e ln n (1-\frac{1}k)^{k\ln n}\le e^{-\ln n} (1k1​)klnnelnn O P T k O P T ( 1 ( 1 1 k ) k ) 1 1 e OPT\ge k\ge OPT·(1-(1-\frac{1}k)^k)\ge 1-\frac{1}e OPTkOPT⋅(1−(1k1​)k)≥1e1​,所以近似比为 1 ( 1 1 k ) k 1 1 e 1-(1-\frac{1}k)^k\ge 1-\frac{1}e 1−(1k1​)k1e1​,则对于一个含有 k ln n + 1 k\ln n+1 klnn+1个子集的集合覆盖, k ln n + 1 Θ ( k ln n ) = Θ ( k lg n ) k\ln n+1\Theta(k·\ln n)=\Theta(k\lg n) klnn+1∈Θ(klnn)=Θ(klgn)。

在这里插入图片描述

​ 当我们选择一个集合之后,删除已经被覆盖的元素。然后我们选择每个单位成本最小的集合直到覆盖所有元素。本质上每次选择覆盖未覆盖元素最多的集合。

  1. C
  2. C
  3. C:代表到目前为止涵盖的元素集

  1. cost effectiveness , or α
  2. \text{cost effectiveness , or α}
  3. cost effectiveness , or α:每个新覆盖节点的平均成本

​ 伪代码:

  1. Greedy Method:
  2. Initial C
  3. While C != U:
  4. Find the set Si whose cost effectiveness is the smallest
  5. then Set C = CSi
  6. Let α= wi/|Si-C|
  7. For each eSi-C : Set price(e)= α
  8. end While
  9. Output Selected sets

我们每次选取的都是

  1. w
  2. i
  3. S
  4. i
  5. C
  6. \cfrac{w_i}{S_i-C}
  7. Si​−Cwi​​最小的集合
  8. S
  9. i
  10. S_i
  11. Si​,即每次新添的集合
  12. S
  13. i
  14. S_i
  15. Si​的新增覆盖率相对于
  16. cost
  17. \text{cost}
  18. cost值都是最大的,从而实现局部最优。

选择的集合按照先后顺序为

  1. S
  2. 1
  3. ,
  4. S
  5. 2
  6. ,
  7. ,
  8. S
  9. m
  10. S_1 , S _2 , , S _m
  11. S1​,S2​,…,Sm
  12. n
  13. i
  14. n _i
  15. ni 是选择
  16. S
  17. i
  18. S_i
  19. Si​时,其覆盖的新元素个数。

元素被覆盖的顺序

  1. e
  2. 1
  3. ,
  4. e
  5. 2
  6. ,
  7. ,
  8. e
  9. n
  10. e_1,e_2,…,e _n
  11. e1​,e2​,…,en

  1. S
  2. j
  3. S_j
  4. Sj​第一次覆盖新元素
  5. e
  6. k
  7. e_k
  8. ek
  9. C
  10. 1
  11. ,
  12. .
  13. .
  14. .
  15. C_1,...
  16. C1​,...是最优覆盖中的部分集合,覆盖了
  17. e
  18. k
  19. ,
  20. ,
  21. e
  22. n
  23. n
  24. i
  25. e_ k , , e _nn _i'
  26. ek​,…,en​,ni′​ 是其覆盖的对应元素个数。不仅仅是
  27. e
  28. k
  29. ,
  30. ,
  31. e
  32. n
  33. e_ k ,…,e_ n
  34. ek​,…,en​ 中的元素。
    1. i n i n k + 1 , i c o s t ( C i ) O P T \sum_i n_i'\ge n-k+1, \sum_i cost(C_i)\leq OPT ∑i​ni′​≥n−k+1,∑i​cost(Ci​)≤OPT,因为 C i , . . . C_ i , . . . Ci​,...也可能覆盖了其他元素,是从最优覆盖中选择的部分集合。
    1. C 1 , . . . . C_1 ,.... C1​,....没有与 S 1 , . . . S j 1 S_1,...S_{j-1} S1​,...Sj1​重复的。假设某个 C i C_i Ci S 1 , . . . S j 1 S_1,...S_{j-1} S1​,...Sj1​中,则 e k e_k ek​之后的元素会被某个 S i ( i [ 1 , j 1 ] ) S_i(i\in[1,j-1]) Si​(i∈[1,j1])覆盖,矛盾。
    1. i c o s t ( C i ) i n i O P T n k + 1 \cfrac{\sum_i cost(C_i) }{\sum_i n_i'}≤ \cfrac{O P T}{n − k + 1}\Longrightarrow ∑i​ni′​∑i​cost(Ci​)​≤n−k+1OPT​⟹存在某个 c o s t ( C i ) n i ′ ≤ O P T n − k + 1 \cfrac{cost(C_i)}{n_i′}≤ \cfrac{O P T}{n − k + 1} ni​′cost(Ci​)​≤n−k+1OPT​。
  1. 由贪心算法选出的 c o s t ( S j ) n j ≤ c o s t ( C i ) n i ′ \cfrac{cost(S_j)}{n_j}≤ \cfrac{cost(C_i)}{n_i′} nj​cost(Sj​)​≤ni​′cost(Ci​)​。
  2. 对于每个 k k k都存在满足 3 3 3和 4 4 4的 C i C_i Ci​
  3. 每个点被覆盖的代价 c o s t ( e k ) ≤ c o s t o p t ( S ) n − k + 1 cost(e_k)\le \frac {cost_{opt}(S)}{n-k+1} cost(ek​)≤n−k+1costopt​(S)​,所以在整个贪心过程中的总代价为 ∑ c o s t ( e k ) ≤ ( 1 + 1 2 + 1 3 + ⋅ ⋅ ⋅ 1 n ) ⋅ c o s t o p t = H n ⋅ c o s t o p t \sum cost(e_k)\le(1+\frac12+\frac13+···\frac1n)·cost_{opt} =H_n·cost_{opt} ∑cost(ek​)≤(1+21​+31​+⋅⋅⋅n1​)⋅costopt​=Hn​⋅costopt​
    1. k c o s t ( e k ) k c o s t ( C i ) n i k O P T n k + 1 ln n O P T \sum_kcost(e_k)\leq \sum_k\cfrac{cost(C_i)}{n_i′} \leq \sum_k\cfrac{O P T}{n k + 1}∼\ln n·OPT kcost(ek​)≤∑kni​′cost(Ci​)​≤∑knk+1OPT​∼lnnOPT.

所以近似比为

  1. ln
  2. n
  3. \ln n
  4. lnn

本文转载自: https://blog.csdn.net/weixin_56462041/article/details/128020362
版权归原作者 之墨_ 所有, 如有侵权,请联系我们删除。

“算法导论习题—摊还时间代价分析、栈实现队列、贪心算法近似比、集合覆盖问题”的评论:

还没有评论