采用Python实现四种最大公约数(greatest common divisor)算法,并比较评估性能。
算法原理:
1、辗转相除法:
已知a,b,c为正整数,若a除以b余c,则GCD(a,b)=GCD (b,c)。
2、更相减损术:
任意给定两个正整数,若是偶数,则用2约简。
以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。
继续这个操作,直到所得的减数和差相等为止。
3、除穷举法:
将小数依次除N(N为从1开始的自然数,结果不为整数则跳过),对得到的数判断其是否可被大数整除。
4、减穷举法:
将小数依次减1,对得到的数判断其是否可被两数整除。
评估结果:
计算两个随机数的最大公约数,比较四种算法的循环次数、耗时。
辗转相除法、更相减损术的效率远高于穷举法,且这两个方法的计算规模几乎不受计算对象量级的影响。
辗转相除法的效率最高,更相减损术次之。除穷举法的效率高于减穷举法。
结果1:(百万级)
GCD of (4456836, 6457982):
辗转相除法: 2 (15次, 0.000s)
更相减损术: 2 (52次, 0.001s)
除穷举法: 2 (2228418次, 2.023s)
减穷举法: 2 (4456835次, 4.093s)
结果2:(千万级)
GCD of (12689792, 12690312):
辗转相除法: 8 (6次, 0.000s)
更相减损术: 8 (24418次, 0.022s)
除穷举法: 8 (1586224次, 1.471s)
减穷举法: 8 (12689785次, 12.072s)
结果3:(亿级)
GCD of (135034734, 749274957):
辗转相除法: 3 (19次, 0.000s)
更相减损术: 3 (112次, 0.000s)
除穷举法: 3 (45011578次, 41.658s)
减穷举法: 3 (135034732次, 129.202s)
源代码如下:
#! usr/bin/env python
import random, time
#最大公约数(辗转相除法)
def gcd1 (num1, num2):
t = time.time()
if num1 < num2: #调整大小顺序
num1, num2 = num2, num1
else:
pass
count = 1
while num2 != 0: #辗转相除
num1, num2 = num2, num1 % num2
count += 1
return [num1, count, time.time() - t]
#最大公约数(更相减损术)
def gcd2 (num1, num2):
t = time.time()
a = 1
while (num1 % 2 ==0) and (num2 % 2 ==0): #均为偶数除2
num1, num2 = num1 / 2, num2 / 2
a *= 2
count = 1
while num2 != 0: #更相减损术
if num1 < num2: #调整大小顺序
num1, num2 = num2, num1
num1, num2 = num2, num1-num2
count += 1
return [num1 * a, count, time.time() - t]
#最大公约数(除穷举法)
def gcd3 (num1, num2):
t = time.time()
if num1 > num2: #取初始值
a = num2
b = num1
else:
a = num1
b = num2
count = 1
a_0 = a
while (b % a != 0): #穷举
if a_0 % (count +1) == 0:
a = a_0 / (count +1)
count += 1
return [a, count, time.time() - t]
#最大公约数(减穷举法)
def gcd4 (num1, num2):
t = time.time()
if num1 > num2: #取初始值
a = num2
else:
a = num1
count = 1
while (num1 % a != 0) | (num2 % a != 0): #穷举
a -= 1
count += 1
# if count >= 1e6:
# a = 0
# break
return [a, count, time.time() - t]
def main():
rg = 1E8
a = random.randrange(rg)
b = random.randrange(rg)
g1 = gcd1(a, b)
g2 = gcd2(a, b)
g3 = gcd3(a, b)
g4 = gcd4(a, b)
print('GCD of (%d,%d):' % (a, b))
print('辗转相除法:%d(%d次,%.3fs)' % (g1[0], g1[1], g1[2]))
print('更相减损术:%d(%d次,%.3fs)' % (g2[0], g2[1], g2[2]))
print('除穷举法:%d(%d次,%.3fs)' % (g3[0], g3[1], g3[2]))
print('减穷举法:%d(%d次,%.3fs)' % (g4[0], g4[1], g4[2]))
if __name__ == '__main__':
main()