分治法补充_多项式乘积的分治算法
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
例4.11:设多项式 p(x) = 1+ x - x2 + 2x3 q(x) = 1- x + 2x2 – 3x3 用分治法计算这两个多项式的乘积。
多项式乘积的分治算法实例
解:n=4,n/2=2,划分多项式得: p(x) = (1+ x) +(-1 + 2x)x2 q(x) = (1- x) +(2 – 3x)x2
多项式乘积分治算法描述:
void PolyMulti (int p[],int ps, int q[], int qs,
int r[],int rs,int n) { 定义r1,r2,r3,r4为数组,大小为2*n-1。元素初始为0。 if(n==2) 直接计算r[rs],r[rs+1],r[rs+2]; else{ k = n/2; PolyMulti(p,0,q,0,r,rs,k); //r0 =p0*q0 PolyMulti(p,k,q,k,r1,n+rs,k); //r1 = p1*q1 PolyAdd(p,0,p,k,r3,0,k); //r3 = p0+p1 PolyAdd(q,0,q,k,r4,0,k); //r4 = q0+q1 PolyMulti(r3,0,r4,0,r2,k+rs,k); //r2 = r3*r4
r2数组: r1数组: r2结果:
-1
9
-11 -2 7 -6
1
2
-5
多项式乘积的分治算法实现
r0(x) = r0(x) + r2(x)(计算r0(x) + r2(x)xk)
r0 从k开始,r2从k开始,长度为2k-1的对应元素相加
r0数组: 1 r2数组: r0结果: 1
0
-1 1 2 2 -5 -5
• 由于B、C两个数组已经进行了排序,因此有效地统计B、
C两个数组之间的“逆序对”的个数。这一统计步骤可在
线性时间内完成的。 • 排序的过程可在递归求解子问题时完成,算法的时间复
杂度为O(nlogn)。
• 虽然对B、C两个序列当中的元素进行了排序,使得序列A 当中某一部分元素的顺序被打乱了,但由于求解过程是 递归定义的,在排序之前B、C两个序列各自其中的元素 之间的“逆序对”个数已经被统计过了,并且排不排序 对统计B、C两个数组之间的“逆序对”的个数不会产生 影响。所以排序过程对整个问题的求解的正确性是没有 任何影响的。
分析
• 简单的算法——穷举算法,即对数组中任意的两
个元素进行判断,看它们是不是构成“逆序对”, 因此这种算法的时间复杂度为O(N2)。
• 首先将这一序列A一分为二,分成两个不同的序列B、C • 如果求出了B,C的逆序对,那么可由B,C求出A的逆序对.
• 假设f(i,j)为i到j号元素中的逆序对个数,取一个分割点k,
p( x) p0 ห้องสมุดไป่ตู้ x) p1 ( x) x n / 2
q( x) q0 ( x) q1 ( x) x n / 2
求解、组合:
p( x)q( x) p0 ( x)q0 ( x) [ p1 ( x)q0 ( x) p0 ( x)q1 ( x)]x n / 2 p1 ( x)q1 ( x) x n
2n k 1 n n 1
ank bk x n ... (a1b0 a0b1 ) x a0b0
k 0
n
直接解:n=2,多项式只有两个系数,直接 乘 p( x)q( x) a0b0 (a0b1 a1b0 ) x a1b1 x 2
划分:当n>2,为降阶,将p(x)、q(x)分别划 分为两个多项式:
多项式乘积的分治算法实现
r2(x)= r2(x) –r0(x)
r2 从k开始,r0从0开始,长度为2k-1的对应元素相减
r2数组: r0数组: 1 r2结果: 0
0 -1 -1
9
-12
9
-11
多项式乘积的分治算法实现
r2(x)= r2(x) –r1(x)
r2 从k开始,r0从n开始,长度为2k-1的对应元素相减
求逆序对个数
• 有一实数序列A[1]、A[2] 、A[3] 、……A[n-1] 、A[n],若 i<j,并且A[i]>A[j],则称A[i]与A[j]构成了一个逆序对,求 数列A中逆序对的个数。 • n≤10000。 • 例如,5 2 4 6 2 3 2 6,可以组成的逆序对有 (5 2),(5 4),(5 2),(5 3),(5 2), (4 2),(4 3),(4 2), (6 2),(6 3),(6 2), (3 2) • 共:12个
2
p( x)q( x) r0 ( x) (r2 ( x) r0 ( x) r1 ( x)) x r1 ( x) x
r0 ( x) (1 x)(1 x) 1 x 2 r1 ( x) (1 2 x)(2 3x) 2 7 x 6 x 2 r2 ( x) (1 x 1 2 x)(1 x 2 3x) 9 x 12x 2
多项式乘积的分治算法
问题描述:已知多项式
p ( x) a0 a1 x ... an x q ( x) b0 b1 x ... bn x
计算p(x)*q(x)。
n n
为均匀划分,以下均假设多项式的系数个数n=2k。
多项式乘积的直接计算
多项式乘积:乘法(n+1)2次,加法n(n+1)次。
4
多项式乘积的分治算法实例
p( x)q( x) 1 x 2 (9 x 12x 2 1 x 2 2 7 x 6 x 2 ) x 2 (2 7 x 6 x 2 ) x 4 1 x 2 (1 2 x 5x 2 ) x 2 2 x 4 7 x 5 6 x 6 1 2x3 7 x 4 7 x5 6x6
0
0
多项式乘积的分治算法实现
r0(x) = r0(x) + r1(x)(计算p(x)q(x))
r0 从n开始,r1从n开始,长度为2k-1的对应元素相加
r0数组: 1 r1数组: r0结果: 1 计算结果
0
0
2
-5 -2 7 7 -6 -6
0
0
2
-7
多项式乘积的分治算法实现
根据上述数组变化,定义函数: void PolyAdd(int p[],int ps, int q[], int qs, int r[],int rs,int k) //r[rs+i] = p[ps+i] + q[qs + i] i=0,…,k-1
分治算法时间复杂度:
T (2) O(1) n2 T (n) 4T (n / 2) O(n) n 2
用递推法解,有T(n)=O(n2)。
上述划分后分块直接乘的分治算法并未降低
O(n2)的时间复杂性,其原因是算法中的多
项式乘积次数为四次。有效的分治算法是设
法降低多项式乘积次数。
多项式乘积的分治算法实现
多项式p(x)、q(x)、p(x)q(x)均用数组存放。 输入:多项式系数个数n
含n个元素的数组p—p(x)的系数
含n个元素的数组q—q(x)的系数
输出:含2n-1个元素的数组r0—p(x)q(x)的系数
多项式乘积的分治算法实现
多项式分治算法实现的关键在于计算过程中r0、r1、 r2元素存放位置及计算时p,q的起始位置和涉及的元 素个数。 下面以例4.11为例观察各数组变化。
void PolyMinus(int p[],int ps, int q[], int qs, int k) //p[ps+i] = p[ps+i] – q[qs+i] i=0,…,k-1
多项式乘积的分治算法实现
void PolyMulti (int p[],int ps, int q[], int qs, int r[],int rs,int n) //p(x) = p[ps] + p[ps+1]x + …+ p[ps+k-1]xn-1 //q(x) = q[qs] +q[qs+1]x + … + q[qs+k-1]xn-1 //r(x) = p(x)q(x)xrs 计算多项式乘积c(x) = p(x)q(x)即调用: PolyMulti(p,0,q,0,c,0,n),即
求解、组合改进:
p( x)q( x) p0 ( x)q0 ( x) [ p1 ( x)q0 ( x) p0 ( x)q1 ( x)]x n / 2 p1 ( x)q1 ( x) x n
( p0 ( x) p1 ( x))(q0 ( x) q1 ( x)) p0 ( x)q0 ( x) p1 ( x)q0 ( x) p0 ( x)q1 ( x) p1 ( x)q1 ( x)
改进后的分治算法乘积次数为三次。 改进分治算法时间复杂度:
T (2) O(1) n2 T (n) 3T (n / 2) O(n) n 2
用递推法解,有T(n)=O(nlog3)。
改进分治算法的时间复杂性O(nlog3),优于直 接乘积的O(n2),其原因在于降低了低阶多项式乘 积次数。 该思想也被用于后续的矩阵乘积和大整数乘 法分治算法中,它们都是通过降低低阶乘积次数 达到改进时间复杂性的目的。
多项式加、减:加、减法(n+1)次。
为降低n次多项式乘积的时间复杂性,可将其转 换为低阶多项式的乘积,且尽量减少乘积次数, 增加多项式加减次数。
an x an1x
n
n1
... a1x a0
*
bn xn bn1 xn1 ... b1 x b0
anb0 xn an1b0 xn1 ... a1b0 x a0b0
记:r0 ( x) p0 ( x)q0 ( x)
r1 ( x) p1 ( x) q1 ( x)
r2 ( x) ( p0 ( x) p1 ( x))(q0 ( x) q1 ( x))
p( x)q( x) r0 ( x) (r2 ( x) r0 ( x) r1 ( x)) x n / 2 r1 ( x) x n
假设s(i,j,k)表示以k为分割点,第一个元素在i到k中,第 二个元素在k+1到j中形成的逆序对数。
f(i,j)=f(i,k)+f(k+1,j)+s(i,j,k)。
• 更小规模的f可以递归求解 • 如何来统计序列B和序列C之间的“逆序对”呢?
提示
• 在递归的求解B、C两个序列中的逆序对的个数以后,如 果对B、C两个序列当中的元素进行排序的话,要统计B、 C两个序列之间的“逆序对”是非常容易的. • 如图 • 排序前 • 排序后 在B数组当中,首先,B中的6,5,4都与C数组当中的3, 2,2都构成了“逆序对”,而2不会构成逆序对,因此B、 C两个数组之间构成的逆序对的个数为3+3+3=9。
r0数组: 1
0
-1
多项式乘积的分治算法实现
计算r1:r1(x)=p1(x)q1(x)=(-1+2x)(2-3x)
p、q从k开始,长度为k的元素组成的多项式的乘积
r1在p(x)q(x)最低次为n,最高次2n-2。
r1数组:
-2
7
-6
多项式乘积的分治算法实现
计算r2:r2(x)=(p0(x)+p1(x))(q0(x)+q1(x))
r3(x) = p0(x)+p1(x) r3数组: 0 3
r4(x) = q0(x)+q1(x) r4数组: 3
-4
多项式乘积的分治算法实现
r2(x) = r3(x)r4(x)
r3、r4从0开始,长度为k的元素组成的多项式的乘积 r2在p(x)q(x)最低次为k,最高次3k-2。
r2数组:
0
9
-12
px1x12xx21qx1x23xx220rxrxqxp??r2x32x2多项式乘积的分治算法实例4110xxrxrx???2221201293212116723221111xxxxxxxrxxxxxrxxxxr??????????????????????654222422222267252116726721129?1xxxxxxxxxxxxxxxxxxqxp???6???3??????????????多项式乘积的分治算法实例5467721xxxx?????多项式乘积的分治算法实现多项式pxqxpxqx均用数组存放
anb1xn1 an1b1xn ... a1b1x2 a1b0 x
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
anbn x2n ... a1bn xn1 a0bn xn
anbn x ...... an1k bk x
多项式乘积的分治算法实现
初始:n=4,令k=n/2=2
1 1 k -1 2
p数组:
p0 1 q数组: -1 q0 2 k p1 -3 q1
多项式乘积的分治算法实现
计算r0:r0(x)=p0(x)q0(x)=(1+x)(1-x)
p、q从0开始,长度为k的元素组成的多项式的乘积
r0在p(x)q(x)中最低次为0,最高次2k-2。