python求两个数的最大公约数穷举法_最大公约数GCD算法

采用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()

你可能感兴趣的:(python求两个数的最大公约数穷举法_最大公约数GCD算法)