辗转相除法(欧几里德算法)

这个算法可以用来求解两个非负整数 a,ba,b 的最大公因数 \gcd\left({a,b}\right)gcd(a,b)。算法的步骤如下:

  1. 若 b=0b=0,则最大公因数是 aa
  2. 否则,最大公因数是 \gcd\left({b,a-b\left\lfloor{\frac{a}{b}}\right\rfloor}\right)gcd(b,abba)

这个算法用自己定义了自己,也就是 递归 的。

这个算法的最早出现在《原本》(欧几里得著)中,用于求解两条线段的“最大共度”,因此也叫做“欧几里德算法”。这个算法也出现在《九章算术》中,叫做“更相减损术”。从细节上看,“更相减损术”有一个预判两个数是否都是偶数的过程,不过“更相减损”的过程和这个算法是一致的。证明辗转相除法可以停下,我们构造一个辅助函数 

f\left({a,b}\right)=a+2bf(a,b)=a+2b。对于非负整数 a,ba,bf\left({a,b}\right)f(a,b) 也是一个非负整数。

下面我们用所谓的 递降法 证明算法将会停下。

如果算法选择了步骤 1(b=0b=0),则算法已经停止;否则,算法将选择步骤 2(将 a,ba,b 替换为 b,a-b\left\lfloor{\frac{a}{b}}\right\rfloorb,abba),那么有

\begin{array}{rcl}f\left({b,a-b\left\lfloor{\frac{a}{b}}\right\rfloor}\right)-f\left({a,b}\right)&=&a-b-2b\left\lfloor{\frac{a}{b}}\right\rfloor\\\\&\leq&a-b-b\left\lfloor{\frac{a}{b}}\right\rfloor\\\\&<&a-b-b\left({\frac{a}{b}-1}\right)\ =\ 0.\end{array}f(b,abba)f(a,b)=<ab2bbaabbbaabb(ba1) = 0.

这说明,只要算法不结束,ff 的值在严格下降,但是起初 f=a+2bf=a+2b 是一个有限的数,因此不可能无限下降下去。因此,算法在某个时刻会停下。我们知道这个算法可以停下来了,那么,算法给出的数是否是正确的呢?当然是,下面我们就会证明这件事情。

命题 \forall k\in\mathbb{Z}, \gcd\left({a,b}\right)=\gcd\left({b,a-kb}\right).kZ,gcd(a,b)=gcd(b,akb).

证明 设 x=\gcd\left({a,b}\right)x=gcd(a,b),则 x|a, x|bxa,xb,从而 x|b, x|{a-kb}xb,xakb,于是我们有

\gcd\left({a,b}\right)=x\leq\gcd\left({b,a-kb}\right).gcd(a,b)=xgcd(b,akb).

同理, \gcd\left({a-kb,b}\right)\leq\gcd\left({b,a-kb-\left(-k\right)b}\right).gcd(akb,b)gcd(b,akb(k)b).

再利用 \gcdgcd 的对称性,有 \gcd\left({a-kb,b}\right)=\gcd\left({b,a-kb}\right)gcd(akb,b)=gcd(b,akb) 和 \gcd\left({b,a-kb-\left(-k\right)b}\right)=\gcd\left({a,b}\right)gcd(b,akb(k)b)=gcd(a,b),于是命题得证。

现在只要取 k=\left\lfloor{\frac{a}{b}}\right\rfloork=ba 就证明了辗转相除法的 输出的正确性

至此,我们已经完整地证明了辗转相除法的 正确性,它包括辗转相除法的 可终结性 和它的 输出的正确性。下一节,你将使用 第二归纳法 重新证明辗转相除法的 可终结性,别担心,核心思路是一样的,只是换一种叙述方式

你可能感兴趣的:(辗转相除法(欧几里德算法))