Python 优化列表理解以找到余素数对
给定A,B打印对数(A,B),使GCD(A,B)=1,1根据这一点应生成所有共模:Python 优化列表理解以找到余素数对,python,list,tuples,list-comprehension,greatest-common-divisor,Python,List,Tuples,List Comprehension,Greatest Common Divisor,给定A,B打印对数(A,B),使GCD(A,B)=1,1根据这一点应生成所有共模: from collections import deque def coprimes(): tree = deque([[2, 1], [3, 1]]) while True: m, n = tree.popleft() yield m, n tree.append([2 * m - n, m]) tree.append([2 *
from collections import deque
def coprimes():
tree = deque([[2, 1], [3, 1]])
while True:
m, n = tree.popleft()
yield m, n
tree.append([2 * m - n, m])
tree.append([2 * m + n, m])
tree.append([m + 2 * n, n])
这不是最快的算法,但最容易理解。另请参见,因为您需要计算每对数字的gcd==1,所以您应该预先计算所有的素因子集。这样,您可以稍后通过检查两个数的素因子集的交集来非常快速地确定它们是否是互质的。我们可以用一种快速的方法来实现这一点
factors = [set() for n in range(N)]
factored = collections.defaultdict(set)
for n in range(2, N):
if not factors[n]: # no factors yet -> n is prime
for m in range(n, N, n): # all multiples of n up to N
factors[m].add(n)
factored[n].add(m)
在此之后,factors[n]
将保存一组n
(duh)的所有素因子,以及factored[n]
由n
分解的所有数字。现在这将派上用场,因为否则我们仍然需要检查多达10000 x 10000对的数字,这在Python中仍然是相当慢的。但是结合使用因子
和因子
集,我们现在可以通过消除与n
共享素数因子的数字,快速找到给定数字的所有共素数
for n in range(1, N):
coprimes = set(range(1, N)) # start with all the numbers in the range
for f in factors[n]: # eliminate numbers that share a prime factor
coprimes -= factored[f]
print "%d is coprime with %r others" % (n, len(coprimes))
对于
N==100
而言,结果在我看来似乎是合理的,而对于N==10000
而言,在我的计算机上大约需要10秒钟。这可能需要一些工作来适应您的实际问题,但我想这是一个好的开始。查找“相对素数”。记住您的gcd函数由于您正在执行gcd
检查二次数对,您应该花时间预算所有数字的素数因子集;那么,找出两个数是否是同素数是一个简单的集合交集问题。@MartijnPieters:这是完全相同的事情吗?用A,B BTW计算成对的最快的方法:我不认为这是一个重复,因为这个问题是测试许多对数字,因此可能有不同的算法需要考虑。
for n in range(1, N):
coprimes = set(range(1, N)) # start with all the numbers in the range
for f in factors[n]: # eliminate numbers that share a prime factor
coprimes -= factored[f]
print "%d is coprime with %r others" % (n, len(coprimes))