我已经制作了一个用于产生素数的筛子。我正在做一个关于RSA的学校项目,其中包括一些编程。我会将质数用于RSA系统,但因为它适用于我的论文,所以安全性并不重要。然而,大素数更具挑战性,我喜欢这样。 我使用的代码:
def Zeef(a):
import math
upperBound = a
upperBoundSquareRoot = int(math.sqrt(upperBound))
isPrime = [1 for m in range (0,upperBound+1)]
for m in range(2,upperBoundSquareRoot+1):
if (isPrime[m]==1):
for k in range(m*m,upperBound+1,m):
isPrime[k] = 0;
print("Priemgetallen : ")
numberofPrimes = 0
for m in range(2,upperBound+1):
if (isPrime[m] ==1):
print(m)
numberofPrimes = numberofPrimes+1
print("Aantal = " , numberofPrimes);
a=input("Alle priemgetallen tot: ")
aa=int(a)
Priemen = Zeef(aa)
我确信有更快的方法来生成素数,但我现在对改进我的代码并不感兴趣。
当我运行这个函数时,它可以很好地生成最多7位的素数,但是当我想要更多时,它真的很慢。我的电脑(8gb ram)给出一条消息,说明内存不足。我在Processing中使用了相同的算法,这是另一种工具。处理非常快,但它不能识别超过10位数。 我还注意到,当我生成计算机能够计算的质数时,打印速度很慢。
我开始在网上搜索,我发现编译我的程序会加快进度,但我不确定它是否加快了计算和打印部分或只是解释部分。 我还发现了一些关于数组的numpy,但我不确定这是否会显着加快我的功能。
如何更快地找到素数?
答案 0 :(得分:2)
这是使用numpy的未经优化的Erathostenes筛选版本。在运行64位版本的Python(2.7)和Numpy(1.7)的8GB笔记本电脑上,它可以在一分钟内计算出高达10 ^ 9的素数因素:
import numpy as np
def sieve(a):
upper_bound = np.int(np.sqrt(a))
is_prime = np.ones((a+1,), dtype=np.bool)
for m in xrange(2, upper_bound+1):
if is_prime[m]:
is_prime[m*m::m] = False
return np.where(is_prime)[0][2:]
>>> sieve(100)
array([ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59,
61, 67, 71, 73, 79, 83, 89, 97], dtype=int64)
以下是我的时间:
%timeit sieve(10**9)
1 loops, best of 3: 33.4 s per loop
%timeit sieve(10**8)
1 loops, best of 3: 2.47 s per loop
%timeit sieve(10**7)
1 loops, best of 3: 207 ms per loop
%timeit sieve(10**6)
100 loops, best of 3: 7.47 ms per loop
%timeit sieve(10**5)
1000 loops, best of 3: 716 us per loop
你可以通过从筛子中删除所有偶数来使它的运行速度提高两倍,但即使使用了这个和世界上所有的内存,你仍然需要几分钟才能将所有素数都提升到10 ^ 10。
答案 1 :(得分:1)
您正在谈论computational complexity的问题。有一些问题,无论处理器或编译器有多快,你都无法加快算法速度。例如,如果您尝试求解NP-complete problem,则对于较小的值很容易,但对于较大的值则很难。
我建议您改进代码,即使您不想这样做。或者,找到一个自己处理素数生成的库。这是一个有趣的链接:http://rebrained.com/?p=458
这似乎是用于生成素数的非常好的代码......但它也没有生成大质数(我在非常快的iMac上尝试过)。它快速达到约100000.我建议查看this SO问题,了解如何测试随机生成的大数字的素数。
答案 2 :(得分:1)
如果要生成RSA算法所需的各种大素数,则需要比Eratosthenes的Sieve更好的算法。这是Python的Miller-Rabin素性检查器的实现:
def isPrime(n):
def isSpsp(n, a):
d, s = n - 1, 0
while d % 2 == 0: d, s = d / 2, s + 1
t = pow(a, d, n)
if t == 1: return True
while s > 0:
if t == n - 1: return True
t, s = (t * t) % n, s - 1
return False
ps = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
if n in ps: return True
for p in ps:
if not isSpsp(n, p): return False
return True
如果您对素数编程感兴趣,我在我的博客上谦虚地推荐这个essay;您也可以查看我博客上的其他一些页面,包括生成RSA半素数的this one。