浅谈 分而治之-欧几里得算法

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

浅谈 分而治之-欧几里得算法

此问题讨论来源于《算法图解》[美] Aditya Bhargava

一、抛出问题

假设你有一小块田地,面积是1680*640。你要将这块地均匀地分成方块,并且分出地方块要尽可能大,你该如何分?

首先你可能想到,我直接对半分一下就好了,但是题中是需要分成的是方块;那你可能想到,我先按方块来分,然后对剩下不是方块的部分,我再分成方块。但是这就违背了均匀的题意。所以,应该如何来分呢?

我们可以使用分而治之的思想来解决问题。首先找出一个条件:一条边的长度是另一条边的整数倍。这样分出的土地正好是方块。另外一个就是如何把问题逐步分解来满足这个条件。

  • 首先根据长方形最短的边来分得正方形,但是这会余下一块土地,如图。

在这里插入图片描述

  • 然后对余下的土地重复上述步骤,如图。

在这里插入图片描述

  • 最终会分成一条边是另一条边的倍数,也就达到了第一个条件。所以这块土地可以分成80*80的最大均匀方块。

这个问题用到的就是分而治之的思路,同时里面也有递归的映射,这里就不做讨论了。

但是为什么会有这么一种方法呢?它背后的原理是什么呢?如果深究,就请继续看下面的欧几里得算法。

二、欧几里得算法及证明

一、算法

上面问题的解决归结到数学上,其实就属于求解两个数的最大公约数。说到这里可能很多人明白了,让我们继续往下看吧。 欧几里得算法是求解最大公约数。A和B的最大公约数使用GCD(A,B)(Greatest Common Divisor)表示。它的性质是:

  • 如果A=0,GCD(0,B) = B,GCD(A,B) = B;
  • 如果B=0,GCD(A,0) = A,GCD(A,B) = A;
  • 如果A,B不为0.那么找出A = B*Q + R.得出GCD(A,B) = GCD(B,R)。然后重复此步骤直到满足性质一或者性质二,也即A=0或B=0;其中Q为整数,R为在0到B-1之间的整数;

使用此算法来计算上述例子,你就会发现上述例子思想就是欧几里得算法。

若你想继续深究,可以继续往下阅读欧几里得算法的性质证明,看看它是如何得出上面三个性质的。

二、证明

下面我们来证明欧几里得算法如何求得A和B的最大公约数。 首先看前两条性质,如果B=0,GCD(A,0) = B,GCD(A,B) = A;

  • 能整除A的最大整数是A;
  • 对于任何整数C,我们写成 C*0 = 0,我们可以得到任何整数都可以整除0;所以我们可以得出A可以整除0。也可以理解成,A是0的约数,0是A的约数;
  • 所以在在0和A中选取最大公约数,那么就是A,所以GCD(A,0) = A;
  • 同理用在A=0的情况

下面我们来看第三条性质。我们需要逐步证明,来让过程看得简单:

要证明GCD(A,B) = GCD(B,R),我们先证明GCD(A,B) = GCD(B,A-B) 我们驾驶有三个数A,B,C,其中C=A-B 1、证明:GCD(A,B)整除C

  • 通过GCD(A,B)的定义来看,GCD(A,B)可以整除A,所以A一定是GCD(A,B)的倍数。例如 X*GCD(A,B) = A
  • 同理B也是GCD(A,B)的倍数Y*GCD(A,B) = B;
  • 因为A - B = C,所以

X * GCD(A,B) - Y * GCD(A,B) = C, (X-Y)GCD(A,B) = C 所以得证GCD(A,B)可以整除C

2、证明:GCD(B,C)可以整除A

  • 同上通过定义,GCD(B,C)可以整除B和C,B,C均为GCD(B,C)的倍数,有:

M * GCD(B,C) = B; N * GCD(B,C) = C

  • 由A-B=C得B+C=A

M * GCD(B,C) + N * GCD(B,C) = A (M+N) GCD(B.C) = A 所以得证

3、证明:GCD(A,B)=GCD(A,A-B)

  • GCD(A,B)可以整除B,上述已证明也可以整除C,所以得出GCD(A,B)是B和C的公约数(不一定是最大公约数)
  • 所以GCD(A,B)一定是小于等于B和C的最大公约数,也即GCD(A,B)小于等于GCD(B,C)
  • 同理,GCD(B,C)可以整除B和A,所以是B和A的公约数,所以有GCD(B,C)小于等于GCD(A,B)
  • 所以得出GCD(A,B) = GCD(B,C),也即GCD(A,B) = GCD(B,C) = GCD(B,A-B)

上述三个证明课=可归纳为此图: 在这里插入图片描述

4、最后证明:GCD(A,B) = GCD(B,R)

  • GCD(A,B) = GCD(B,A-B),其中括号内可以互换顺序,GCD(A,B) = GCD(A-B,B)
  • 由前面证明1和2可知:

GCD(A,B)=GCD(A-B,B)=GCD(A-2B,B)=GCD(A-3B,B)=...=GCD(A-Q⋅B,B)

  • 因为A = B * Q + R,所以R = A-Q * B
  • 所以得证GCD(A,B) = GCD(B,R)

证毕 下面是我的一些学习心得,题外话,大家可看可不看。 我认为我们应该拥有系统性思维,学习知识要由浅入深,再由深入浅。俗话说,先把书本读厚,再把书本读薄。学习不可泛泛而学,模棱两可,能用就用;不可知其然而不知其所以然。学习是需要系统性,打牢基础部分。对于计算机学科来说,数学更是非常重要。所以我们应该系统得去学习,磨炼基础知识,熟练应用解决问题,形成系统,这样才能在学习上更进一步。

人在学习的时候,总会听自己想听的内容,从而会忽略一些重要知识,所以温故知新,建议收藏。

参考网站:www.khanacademy.org/computing/c…

猜你喜欢

转载自juejin.im/post/7112029243017527327