我一直在寻找生成互质对的方法,经过一些搜索,我发现有多个消息来源告诉Farey的序列是最快的算法。以下是其中一些来源:Stackexchange,Quora。
这是Farey的算法和一个简单的GCD:
from itertools import combinations
from math import gcd
def farey(limit):
'''Fast computation of Farey sequence as a generator'''
# n, d is the start fraction n/d (0,1) initially
# N, D is the stop fraction N/D (1,1) initially
pend = []
n = 0
d = N = D = 1
while True:
mediant_d = d + D
if mediant_d <= limit:
mediant_n = n + N
pend.append((mediant_n, mediant_d, N, D))
N = mediant_n
D = mediant_d
else:
yield n, d
if pend:
n, d, N, D = pend.pop()
else:
break
def simple_gcd(limit):
for A, B in combinations(range(limit+1), 2):
if gcd(A, B) == 1:
yield A, B
我检查了它们是否产生相同的输出:
>>> count = 0
>>> for i in farey(10000):
count+=1
>>> count
30397486
>>> count = 0
>>> for i in simple_gcd(10000):
count+=1
>>> count
30397486
他们这样做。
然而我的功能更快(在功能之外更快。)
>>> import timeit
>>> timeit.timeit("for i in farey(10000):pass", "from __main__ import farey", number=1)
16.637074244167408
>>> timeit.timeit("for i in simple_gcd(10000):pass", "from __main__ import simple_gcd", number=1)
16.504983127784428
>>> timeit.timeit("for A, B in itertools.combinations(range(10001), 2):\n if math.gcd(A, B)==1:pass", "import math, itertools", number=1)
15.035244938807324
那么,Farey Sequence真的是生成互质对的最快方法,如果没有,我应该使用什么算法?