矩阵变换在扩展EUCLID算法中的应用
摘要:对于给定的两个正整数a,b, 如何确定两个整数u,v, 使得 au+bv=gcd(a,b), 这里gcd(a,b)表示a,b的最大公约数?本文利用矩阵变换给出两个算法用于求解u,v.
众所周知,对于给定的两个正整数a,b, 求a,b的最大公约数可使用EUCLID算法,其依据是下面的引理。 为了表述方便, 下面均用 a/b表a 除以b的商, a%b表a 除以b的余数.
引理1: 设a,b是两个给定的正整数, a>b. 则 gcd(a, b)=gcd(b, a%b).
引理1的证明可参见文献[1], 这里略去.
我们称 为关于正整数a,b 的变换矩阵。注意到
=
记 a1=b, b1=a%b. 若b1≠0, 则继续对 进行变换,
= =
记 a2= b1, b2=a1%b1. 若b2≠0, 则继续对 进行变换,
… …
… = (1)
直到 ak%bk=0为止。
如此便可得到 gcd(a,b)=bk。记矩阵 … 为 。由等式(1)可得 = , 即ua+vb=bk=gcd(a,b) 。因此只需计算出矩阵 ,…, , 的乘积,便可求出u, v。
初始化 u0=0,v0=1,p0=1, q0=-a/b。若已求出 ,…, , 的积为 , 则 = … = = , 即uk=pk-1,vk=qk-1,pk=uk-1+(-ak/bk)pk-1, qk= vk-1+(-ak/bk)qk-1。
对于给定的两个正整数a,b, 从上面的讨论,我们可给出一个非递归的算法来求出两个整数u,v, 使得 au+bv=gcd(a,b)。
int gcd(int a, int b, int *u, int *v )
/* 不妨设 a>b>0, 用*u, *v返回所求的两个整数, 函数将返回 gcd(a,b) */
{int tempu, tempv, tempa, p,q;
*u=0,*v=1,p=1, q=-a/b; /*初始化 *u,*v,p, q的值*/
while(1)
{ tempa=a; a=b; b= tempa%b; if (b==0)break;
tempu=*u, tempv=*v;
*u=p,*v=q,p= tempu +(-a/b)*p, q= tempv+(-a/b)*q;
}
return a;
}
这个扩展欧几里德在剩余定理里计算M的逆时有所运用。