算法导论学习笔记[2] #20210711

算法导论学习笔记[2] #20210711


lec 3

Lecture 3: Divide-and-Conquer: Strassen, Fibonacci, Polynomial Multiplication

分治法及其应用

Q0: 分治法的步骤除了“分”成子问题和“治”子问题还有什么?对分治法做分析时,主定理中的 f ( n ) f(n) f(n)对应什么?
A0: 把子问题的解合并成为大问题的解。“分”的步骤以及合并的步骤。
实际上:如果明确要使用分治法了,那么需要动脑筋的往往就是如何分,如何合并(而不需要考虑小问题如何解决)。因为分到最小规模后,往往问题的解决方法是平凡的。
Strassen方法说明“分”和“合并”的过程都可能不平凡,富有技巧。
Q1: 举例说明“分”不一定分成大于1个子问题。
A1: 二分查找。
Q2: 对于求 x n x^n xn的分治法,说出三个步骤对应什么。分析复杂度。
A2: 分: x n = x n / 2 x n / 2 x^n=x^{n/2}x^{n/2} xn=xn/2xn/2 x n = x [ n / 2 ] x [ n / 2 ] x x^n=x^{[n/2]}x^{[n/2]}x xn=x[n/2]x[n/2]x(跟奇偶性有关)。只需要 O ( 1 ) O(1) O(1).
治:实质上只有一个子问题!因为两个 x n / 2 x^{n/2} xn/2是一样的。
归并:乘一次或两次(跟奇偶性有关)。只需要 O ( 1 ) O(1) O(1).
T ( n ) = T ( n / 2 ) + Θ ( 1 ) T(n)=T(n/2)+\Theta(1) T(n)=T(n/2)+Θ(1). 则 l o g b a = 0 , T ( n ) = Θ ( l o g n ) log_b a=0,T(n)=\Theta(logn) logba=0,T(n)=Θ(logn).(注:主定理的Case 2)
Q3: 计算斐波那契数列 F n F_n Fn的朴素递归方法:对于 n = 0 n=0 n=0 n = 1 n=1 n=1是递归出口,对于 n = m n=m n=m直接递归地计算 F m − 2 , F m − 1 F_{m-2},F_{m-1} Fm2,Fm1并相加。请利用递归树方法直观说明该算法具有指数复杂度。
A3: 提示:树每次分岔,规模最多减少2. 树至少 n / 2 n/2 n/2层。再看叶子数。
注:实际上容易看出树的总叶子数是 Θ ( ( 5 + 1 2 ) n ) \Theta((\frac{\sqrt 5+1}{2})^n) Θ((25 +1)n). 所以开销有下界 Ω ( ( 5 + 1 2 ) n ) \Omega((\frac{\sqrt 5+1}{2})^n) Ω((25 +1)n).
Q4: 如何利用Q2解决Q3?
A4: 直接使用斐波那契数列的通项公式会出现浮点数不精确的问题。所以应该考虑矩阵 1 1 1 0 \begin{matrix}1&1\\1&0\end{matrix} 1110 n n n次幂才对。
Q5: 对于矩阵乘法,如果简单的把两个相乘的矩阵都分成4块,再分块相乘,那么是否得到四个子问题?
A5: 不是。为了得到结果的每个小块,需要两次乘法。所以是8个子问题。实际上,这样的分治仍是 n 3 n^3 n3量级。
Q6: 记2个相乘的矩阵的各自4块依次是 A 1 , ⋯   , A 8 A_1,\cdots,A_8 A1,,A8,则我们要求的新矩阵的4块分别是 A 1 A 5 + A 2 A 7 , A 1 A 6 + A 2 A 8 , ⋯   , ⋯ A_1A_5+A_2A_7,A_1A_6+A_2A_8,\cdots,\cdots A1A5+A2A7,A1A6+A2A8,,.
现在考察所有可能的 ∑ i = 1 8 ( a i A i ) ∑ i = 1 8 ( b i A i ) \sum_{i=1}^8(a_iA_i)\sum_{i=1}^8(b_iA_i) i=18(aiAi)i=18(biAi),Strassen算法使用了()个这样的结果,对这些结果通过()运算得到了待求的新矩阵的4块。因此容易证明其复杂度是()。通过这种思想是否有可能得到复杂度在 Θ ( n 2 ) \Theta(n^2) Θ(n2)的算法?
A6: 7,(矩阵)加减法(或:线性组合), Θ ( n l o g 7 ) \Theta(n^{log7}) Θ(nlog7),不可能。因为如果把2个相乘的矩阵各自分成 m 2 m^2 m2块,那么待求新矩阵的 m 2 m^2 m2块在某种意义下“线性无关”,故至少需要 m 2 m^2 m2次矩阵相乘。因此主方法中递推式至少是 T ( n 2 ) = m 2 T ( n 2 / m ) + Θ ( n 2 ) T(n^2)=m^2 T(n^2/m)+\Theta(n^2) T(n2)=m2T(n2/m)+Θ(n2).(“至少”意为 T ( n 2 / m ) T(n^2/m) T(n2/m)前的系数最小是 m 2 m^2 m2),故得到的算法复杂度至少是 Θ ( n 2 l o g n ) \Theta(n^2 logn) Θ(n2logn).
Q7: 对于问题:Embed a complete binary tree with n leaves in a grid using minimal area.(在只能取方格点作为结点,格线作为电路线的电路板上Embed一个完全二叉树)
朴素的想法是把叶子结点排成一排,然后在上面一排放叶子节点的父节点,于是总共有()排,每排宽度是()。
A7: Θ ( l o g n ) \Theta(logn) Θ(logn) Θ ( n ) \Theta(n) Θ(n).
Q8: 为了用分治法解决Q7,我们必须首先意识到分治法往往“分”出的是和原问题“自相似”的问题,这提示我们怎么做?
A8: 把正方形分成四个小正方形(即自相似)。递归表达式为 A r e a ( n ) = 4 A r e a ( n / 4 ) + O ( 1 ) Area(n)=4Area(n/4)+O(1) Area(n)=4Area(n/4)+O(1).
注:仔细观察课件中H-tree embedding的示意图,发现对于 n = 7 n=7 n=7,如果我们把 3 ∗ 3 3*3 33的H形结构当成 A r e a ( 7 ) Area(7) Area(7)将导致考虑 A r e a ( 31 ) Area(31) Area(31)时难以说明递归表达式(因为多出来中间的“十字”)。所以不妨把左上角 4 ∗ 4 4*4 44结构当成 A r e a ( 7 ) Area(7) Area(7). 这样才能说明“合并”的空间代价是 O ( 1 ) O(1) O(1)。(实际上合并的空间代价在这种想法中是0)

おすすめ

転載: blog.csdn.net/tritone/article/details/118658982