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}
Fm−2,Fm−1并相加。请利用递归树方法直观说明该算法具有指数复杂度。
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
3∗3的H形结构当成
A
r
e
a
(
7
)
Area(7)
Area(7)将导致考虑
A
r
e
a
(
31
)
Area(31)
Area(31)时难以说明递归表达式(因为多出来中间的“十字”)。所以不妨把左上角
4
∗
4
4*4
4∗4结构当成
A
r
e
a
(
7
)
Area(7)
Area(7). 这样才能说明“合并”的空间代价是
O
(
1
)
O(1)
O(1)。(实际上合并的空间代价在这种想法中是0)