分治算法 小组的汇报内容:
一、分治算法的基本概念„„„„„„„„„„„„„第2页
二、分治算法的基本思想及策略„„„„„„„„„„第2页
三、分治法适用的情况„„„„„„„„„„„„„„第3页
四、分治法的基本步骤„„„„„„„„„„„„„„第3页
五、分治法的复杂性分析„„„„„„„„„„„„„第4页
六、快速傅里叶变换„„„„„„„„„„„„„„„第5页
七、可使用分治法求解的一些经典问题„„„„„„„第9页
八、依据分治法设计程序时的思维过程„„„„„„„第9页
九、分治法与其它常见算法的比较„„„„„„„„„第9页 小组的分工情况:
彭勇讲前五个部分,天西山讲第六个部分,胡化腾讲最后三个部分,吕璐负责汇报的资料收集,小组分工以及最后的资料整理。
三、分治法适用的情况
分治法所能解决的问题一般具有以下几个特征:
1) 该问题的规模缩小到一定的程度就可以容易地解决
2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。
3) 利用该问题分解出的子问题的解可以合并为该问题的解;
4) 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题。
第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;
第二条特征是应用分治法的前提它也是大多数问题可以满足的,此特征反映了递归思想的应用;、
第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑用贪心法或动态规划法。
第四条特征涉及到分治法的效率,如果各子问题是不独立的则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态规划法较好。
四、分治法的基本步骤
分治法在每一层递归上都有三个步骤:
step1 分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;
step2 解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题
step3 合并:将各个子问题的解合并为原问题的解。
它的一般的算法设计模式如下:
Divide-and-Conquer(P)
1. if |P|≤n0
2. then return(ADHOC(P))
3. 将P 分解为较小的子问题 P1 ,P2 ,...,Pk
4. for i←1 to k
5. do yi ← Divide-and-Conquer(Pi) △ 递归解决Pi
6. T ← MERGE(y1,y2,...,yk) △ 合并子问题
7. return(T)
其中|P|表示问题P 的规模;n0为一阈值,表示当问题P 的规模不超过n0时,问题已容易直接解出,不必再继续分解。ADHOC(P)是该分治法中的基本子算法,用于直接解小规模的问题P 。因此,当P 的规模不超过n0时直接用算法ADHOC(P)求解。算法MERGE(y1,y2,...,yk)是该分治法中的合并子算法,用于将P 的子问题P1 ,P2 ,...,Pk的相应的解y1,y2,...,yk 合并为P 的解。
五、分治法的复杂性分析
一个分治法将规模为n 的问题分成k 个规模为n /m 的子问题去解。设分解阀值n0=1,且adhoc 解规模为1的问题耗费1个单位时间。再设将原问题分解为k 个子问题以及用merge 将k 个子问题的解合并为原问题的解需用f(n)个单位时间。用T(n)表示该分治法解规模为|P|=n的问题所需的计算时间,则有:
T(n )= k T(n/m)+f(n)
通过迭代法求得方程的解:
递归方程及其解只给出n 等于m 的方幂时T(n)的值,但是如果认为T(n)足够平滑,那么由n 等于m 的方幂时T(n)的值可以估计T(n)的增长速度。通常假定
T(n)是单调上升的,从而当 mi≤n
在了解这个算法之前,我们首先必须弄清楚这样几个问题。什么是傅里叶变换?什么是快速傅里叶变换?
傅里叶变换能将满足一定条件的某个函数表示成三角函数(正弦和/或余弦函数)或者它们的积分的线性组合。在不同的研究领域,傅里叶变换具有多种不同的变体形式,如连续傅里叶变换和离散傅里叶变换。最初傅里叶分析是作为热过程的解析分析的工具被提出的。离散傅里叶变换的一种快速算法。所以我们可以了解到快速傅里叶变换就是对离散的点进行处理的算法。今天我们通过两个多项式的乘积来介绍FFT 。
S =P X ∗K(X)
S =(PO +P 1X +P 2X 2+⋯+P n −1X n −1) ∗(K0+K 1X +K 2X 2+⋯+
K n −1X n −1)
在上个式子中,我们得到S 是最高阶位2N-2。我们知道一次函数可以通过二个点来确定这个函数,二次函数可以通过三个点来确定,三次函数可以通过四个点来确定。由此我们可以推想S 可以由2N-1个点上的值确定,事实上也确实如此,证明过程大家下去在研究。这2N-1个点上的值可以通过两个多项式在这些点上的值相乘而得到。由此我们得到两个N-1阶多项式相乘的一般方法,如下所示:
(1) 计算给定的两个多项式在2N-1个不同点上的值。
(2) 在没一点上将两值相乘。
(3) 根据这2N-1个点上的乘积,用内插法求出乘积多项式。
我们来计算这个算法的时间复杂度,可以得知其时间复杂度是N 2级别的。当N 很大时,已不能满足计算要求。必须寻找新的算法来解决这个问题。
下面我向大家介绍用快速傅里叶变换算法解决两个多项式的乘法问题,在算法中用到的思想就是分治的思想。
我们注意到刚才在用2N-1个点计算多项式成绩时,没有特别指定是什么点,只要他们在定义域内即可。这样,如果我们选取特点的2N-1个点,那么就有可能使计算多项式的值和内插变得容易。
01n −1可以选取1的复数跟W n 、W n 、…、W n 来充当这些点。因为1的复数跟
具有周期变化的性质,所以这给计算带来了方便。可能大家已经忘记1的复数跟的表达形式了,我简要给大家介绍一下。
0 Wn =cos 2kπ
n+sin 2kπ
ni (k=0、1、2„„n-1)
这就是1的复数跟形式,具有周期性变化。我们就来验证一下。比如我们取一个多项式最高阶是7,那么它的复数跟就是。
0312W 8=1、W 8=2+2i 、W 8=i、W 8=−54W 8=1、W 8=−( +i 22 67+i )、W =-i、W =−(−+i ) 882222
首先考虑用分治法计算多项式在1的复数跟上的值。即要计算多项式
01n −1 S=(PO +P 1X +P 2X 2+⋯+P n −1X n −1) 在点W n 、W n 、…、W n 上的
值,表示为
y k = n−1
i=0k (w n )i p i ,0
这时,(y 0、y 1、y 2…、y n −1)称为(p 0、p 1、p 2…、p n −1)的离散傅里叶变换,(p 0、p 1、p 2…、p n −1)称为(y 0、y 1、y 2…、y n −1)的傅里叶逆变换。
k 现在用法求多项式在W n (0
次幂和奇次幂两个子多项式。如n=8,则有
P X =P O +P 1X +P 2X 2+⋯+P 7X 7
=P O +P 2X 2+P 4X 4+P 6X 6+X (P 1+P 3X 2+P 5X 4+P 7X 6)
=P (X 2)+P 0(X 2)
01若X 是1的复数根,则X 2也是1的复数根。即设X=W 8,则X 2=W 4,X 4=
23W 4,X 3=W 4,这个计算带来了方便。
若n 是偶数,X 是1的n 次复数根,那么X 2必是1的n/2次方根,又由于P 0(X 2)和P (X 2)是n/2-1阶多项式,所以对P 0(X 2)和P (X 2)只要计算n/2个1的n/2次方根,从而节约了计算量。
比如计算7阶多项式,用一般方法就要计算P (x )在1的8次方根W 8,可以表示为如下:
03031212W 8:W 8、W 8、W 8、W 8、−W 8、−W 8、−W 8、−W 8、
他们的平方是1的4次方根:
201230123W 8:W 4、W 4、W 4、W 4、W 4、W 4、W 4、W 4
用分治法计算P (X )在n 个1的n 次方根上的值
k P W n =n k )+P 0n k )
22
如7次多项式在8个1的8次方根上的值为:
0 0 0 0 P W 8=P W 4+W 8P 0W 4
1 1 1 1 P W 8=P W 4+W 8P 0W 4
2 2 2 2 P W 8=P W 4+W 8P 0W 4
3 3 3 3 P W 8=P W 4+W 8P 0W 4
0 4 4 4 P W 8=P W 4−W 8P 0W 4
5 5 1 5 P W 8=P W 4−W 8P 0W 4
6 6 2 6 P W 8=P W 4−W 8P 0W 4
3 7 7 7 P W 8=P W 4−W 8P 0W 4
设P (X )是n-1阶多项式,M(n)是计算P (X )在n 个点上的值所需要的乘法次数,M (2)是计算2−1阶多项式在2个点上的值所需要的乘法次数。由以上讨论可得如下的地推关系式: M(n)=2 M(2)+ 2(其中2是求X ∗P 0所需要的乘法次数。求解递归关系式 设n=2k
M 2k M 2k −1 1−k =+∗2∗2k 22
M 2k −1 M 2k −2 1−k+1k −1=+∗2∗2 ……
……
……
M 20 1−0=∗2∗20 M 2k 1=(2−k ∗2k +2−k+1∗2k −1+⋯+2−0∗20) 整理得:
1M 2 =(20∗2k +21∗2k −1+⋯+2k ∗20) k n n n n n n
=2∗ k +1 ∗2k =2n logn +1
11
可得M(n)=O(nlogn )。在n 值很大时,nlogn 比n 2节省了很多运算次数,快速傅里叶变换具有很大的优势。 七、可使用分治法求解的一些经典问题
(1)二分搜索
(2)大整数乘法
(3)Strassen 矩阵乘法
(4)棋盘覆盖
(5)合并排序
(6)快速排序
(7)线性时间选择
(8)最接近点对问题
(9)循环赛日程表
(10)汉诺塔
八、依据分治法设计程序时的思维过程
实际上就是类似于数学归纳法,找到解决本问题的求解方程公式,然后根据方程公式设计递归程序。
1、一定是先找到最小问题规模时的求解方法
2、然后考虑随着问题规模增大时的求解方法
3、找到求解的递归函数式后(各种规模或因子),设计递归程序即可。
九、分治法与其它常见算法的比较
1、递归与分治法:
由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。这自然导致递归过程的产生。
分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许
多高效算法。
2、动态规划法与分治法
共同点:将待求解的问题分解成若干子问题,先求解子问题,然后再从这些子问题的解得到原问题的解。
不同点: 1、适合于用动态规划法求解的问题,分解得到的各子问题往往不是相互独立的;而分治法中子问题相互独立。
2、动态规划法用表保存已求解过的子问题的解,再次碰到同样的子问题时不必重新求解,而只需查询答案,故可获得多项式级时间复杂度,效率较高;而分治法中对于每次出现的子问题均求解,导致同样的子问题被反复求解,故产生指数增长的时间复杂度,效率较低。
分治算法 小组的汇报内容:
一、分治算法的基本概念„„„„„„„„„„„„„第2页
二、分治算法的基本思想及策略„„„„„„„„„„第2页
三、分治法适用的情况„„„„„„„„„„„„„„第3页
四、分治法的基本步骤„„„„„„„„„„„„„„第3页
五、分治法的复杂性分析„„„„„„„„„„„„„第4页
六、快速傅里叶变换„„„„„„„„„„„„„„„第5页
七、可使用分治法求解的一些经典问题„„„„„„„第9页
八、依据分治法设计程序时的思维过程„„„„„„„第9页
九、分治法与其它常见算法的比较„„„„„„„„„第9页 小组的分工情况:
彭勇讲前五个部分,天西山讲第六个部分,胡化腾讲最后三个部分,吕璐负责汇报的资料收集,小组分工以及最后的资料整理。
三、分治法适用的情况
分治法所能解决的问题一般具有以下几个特征:
1) 该问题的规模缩小到一定的程度就可以容易地解决
2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。
3) 利用该问题分解出的子问题的解可以合并为该问题的解;
4) 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题。
第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;
第二条特征是应用分治法的前提它也是大多数问题可以满足的,此特征反映了递归思想的应用;、
第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑用贪心法或动态规划法。
第四条特征涉及到分治法的效率,如果各子问题是不独立的则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态规划法较好。
四、分治法的基本步骤
分治法在每一层递归上都有三个步骤:
step1 分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;
step2 解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题
step3 合并:将各个子问题的解合并为原问题的解。
它的一般的算法设计模式如下:
Divide-and-Conquer(P)
1. if |P|≤n0
2. then return(ADHOC(P))
3. 将P 分解为较小的子问题 P1 ,P2 ,...,Pk
4. for i←1 to k
5. do yi ← Divide-and-Conquer(Pi) △ 递归解决Pi
6. T ← MERGE(y1,y2,...,yk) △ 合并子问题
7. return(T)
其中|P|表示问题P 的规模;n0为一阈值,表示当问题P 的规模不超过n0时,问题已容易直接解出,不必再继续分解。ADHOC(P)是该分治法中的基本子算法,用于直接解小规模的问题P 。因此,当P 的规模不超过n0时直接用算法ADHOC(P)求解。算法MERGE(y1,y2,...,yk)是该分治法中的合并子算法,用于将P 的子问题P1 ,P2 ,...,Pk的相应的解y1,y2,...,yk 合并为P 的解。
五、分治法的复杂性分析
一个分治法将规模为n 的问题分成k 个规模为n /m 的子问题去解。设分解阀值n0=1,且adhoc 解规模为1的问题耗费1个单位时间。再设将原问题分解为k 个子问题以及用merge 将k 个子问题的解合并为原问题的解需用f(n)个单位时间。用T(n)表示该分治法解规模为|P|=n的问题所需的计算时间,则有:
T(n )= k T(n/m)+f(n)
通过迭代法求得方程的解:
递归方程及其解只给出n 等于m 的方幂时T(n)的值,但是如果认为T(n)足够平滑,那么由n 等于m 的方幂时T(n)的值可以估计T(n)的增长速度。通常假定
T(n)是单调上升的,从而当 mi≤n
在了解这个算法之前,我们首先必须弄清楚这样几个问题。什么是傅里叶变换?什么是快速傅里叶变换?
傅里叶变换能将满足一定条件的某个函数表示成三角函数(正弦和/或余弦函数)或者它们的积分的线性组合。在不同的研究领域,傅里叶变换具有多种不同的变体形式,如连续傅里叶变换和离散傅里叶变换。最初傅里叶分析是作为热过程的解析分析的工具被提出的。离散傅里叶变换的一种快速算法。所以我们可以了解到快速傅里叶变换就是对离散的点进行处理的算法。今天我们通过两个多项式的乘积来介绍FFT 。
S =P X ∗K(X)
S =(PO +P 1X +P 2X 2+⋯+P n −1X n −1) ∗(K0+K 1X +K 2X 2+⋯+
K n −1X n −1)
在上个式子中,我们得到S 是最高阶位2N-2。我们知道一次函数可以通过二个点来确定这个函数,二次函数可以通过三个点来确定,三次函数可以通过四个点来确定。由此我们可以推想S 可以由2N-1个点上的值确定,事实上也确实如此,证明过程大家下去在研究。这2N-1个点上的值可以通过两个多项式在这些点上的值相乘而得到。由此我们得到两个N-1阶多项式相乘的一般方法,如下所示:
(1) 计算给定的两个多项式在2N-1个不同点上的值。
(2) 在没一点上将两值相乘。
(3) 根据这2N-1个点上的乘积,用内插法求出乘积多项式。
我们来计算这个算法的时间复杂度,可以得知其时间复杂度是N 2级别的。当N 很大时,已不能满足计算要求。必须寻找新的算法来解决这个问题。
下面我向大家介绍用快速傅里叶变换算法解决两个多项式的乘法问题,在算法中用到的思想就是分治的思想。
我们注意到刚才在用2N-1个点计算多项式成绩时,没有特别指定是什么点,只要他们在定义域内即可。这样,如果我们选取特点的2N-1个点,那么就有可能使计算多项式的值和内插变得容易。
01n −1可以选取1的复数跟W n 、W n 、…、W n 来充当这些点。因为1的复数跟
具有周期变化的性质,所以这给计算带来了方便。可能大家已经忘记1的复数跟的表达形式了,我简要给大家介绍一下。
0 Wn =cos 2kπ
n+sin 2kπ
ni (k=0、1、2„„n-1)
这就是1的复数跟形式,具有周期性变化。我们就来验证一下。比如我们取一个多项式最高阶是7,那么它的复数跟就是。
0312W 8=1、W 8=2+2i 、W 8=i、W 8=−54W 8=1、W 8=−( +i 22 67+i )、W =-i、W =−(−+i ) 882222
首先考虑用分治法计算多项式在1的复数跟上的值。即要计算多项式
01n −1 S=(PO +P 1X +P 2X 2+⋯+P n −1X n −1) 在点W n 、W n 、…、W n 上的
值,表示为
y k = n−1
i=0k (w n )i p i ,0
这时,(y 0、y 1、y 2…、y n −1)称为(p 0、p 1、p 2…、p n −1)的离散傅里叶变换,(p 0、p 1、p 2…、p n −1)称为(y 0、y 1、y 2…、y n −1)的傅里叶逆变换。
k 现在用法求多项式在W n (0
次幂和奇次幂两个子多项式。如n=8,则有
P X =P O +P 1X +P 2X 2+⋯+P 7X 7
=P O +P 2X 2+P 4X 4+P 6X 6+X (P 1+P 3X 2+P 5X 4+P 7X 6)
=P (X 2)+P 0(X 2)
01若X 是1的复数根,则X 2也是1的复数根。即设X=W 8,则X 2=W 4,X 4=
23W 4,X 3=W 4,这个计算带来了方便。
若n 是偶数,X 是1的n 次复数根,那么X 2必是1的n/2次方根,又由于P 0(X 2)和P (X 2)是n/2-1阶多项式,所以对P 0(X 2)和P (X 2)只要计算n/2个1的n/2次方根,从而节约了计算量。
比如计算7阶多项式,用一般方法就要计算P (x )在1的8次方根W 8,可以表示为如下:
03031212W 8:W 8、W 8、W 8、W 8、−W 8、−W 8、−W 8、−W 8、
他们的平方是1的4次方根:
201230123W 8:W 4、W 4、W 4、W 4、W 4、W 4、W 4、W 4
用分治法计算P (X )在n 个1的n 次方根上的值
k P W n =n k )+P 0n k )
22
如7次多项式在8个1的8次方根上的值为:
0 0 0 0 P W 8=P W 4+W 8P 0W 4
1 1 1 1 P W 8=P W 4+W 8P 0W 4
2 2 2 2 P W 8=P W 4+W 8P 0W 4
3 3 3 3 P W 8=P W 4+W 8P 0W 4
0 4 4 4 P W 8=P W 4−W 8P 0W 4
5 5 1 5 P W 8=P W 4−W 8P 0W 4
6 6 2 6 P W 8=P W 4−W 8P 0W 4
3 7 7 7 P W 8=P W 4−W 8P 0W 4
设P (X )是n-1阶多项式,M(n)是计算P (X )在n 个点上的值所需要的乘法次数,M (2)是计算2−1阶多项式在2个点上的值所需要的乘法次数。由以上讨论可得如下的地推关系式: M(n)=2 M(2)+ 2(其中2是求X ∗P 0所需要的乘法次数。求解递归关系式 设n=2k
M 2k M 2k −1 1−k =+∗2∗2k 22
M 2k −1 M 2k −2 1−k+1k −1=+∗2∗2 ……
……
……
M 20 1−0=∗2∗20 M 2k 1=(2−k ∗2k +2−k+1∗2k −1+⋯+2−0∗20) 整理得:
1M 2 =(20∗2k +21∗2k −1+⋯+2k ∗20) k n n n n n n
=2∗ k +1 ∗2k =2n logn +1
11
可得M(n)=O(nlogn )。在n 值很大时,nlogn 比n 2节省了很多运算次数,快速傅里叶变换具有很大的优势。 七、可使用分治法求解的一些经典问题
(1)二分搜索
(2)大整数乘法
(3)Strassen 矩阵乘法
(4)棋盘覆盖
(5)合并排序
(6)快速排序
(7)线性时间选择
(8)最接近点对问题
(9)循环赛日程表
(10)汉诺塔
八、依据分治法设计程序时的思维过程
实际上就是类似于数学归纳法,找到解决本问题的求解方程公式,然后根据方程公式设计递归程序。
1、一定是先找到最小问题规模时的求解方法
2、然后考虑随着问题规模增大时的求解方法
3、找到求解的递归函数式后(各种规模或因子),设计递归程序即可。
九、分治法与其它常见算法的比较
1、递归与分治法:
由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。这自然导致递归过程的产生。
分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许
多高效算法。
2、动态规划法与分治法
共同点:将待求解的问题分解成若干子问题,先求解子问题,然后再从这些子问题的解得到原问题的解。
不同点: 1、适合于用动态规划法求解的问题,分解得到的各子问题往往不是相互独立的;而分治法中子问题相互独立。
2、动态规划法用表保存已求解过的子问题的解,再次碰到同样的子问题时不必重新求解,而只需查询答案,故可获得多项式级时间复杂度,效率较高;而分治法中对于每次出现的子问题均求解,导致同样的子问题被反复求解,故产生指数增长的时间复杂度,效率较低。