python中的随机素数

时间:2015-01-08 00:51:46

标签: python random generator list-comprehension primes

我目前已将↓设为我的randprime(p,q)功能。有没有办法通过像 genexp listcomp 之类的东西来缩小它?这是我的职责:

n = randint(p, q)
while not isPrime(n):
    n = randint(p, q)

4 个答案:

答案 0 :(得分:4)

最好只生成素数列表,然后从该行中选择。 就像你的代码一样,如果在区间内没有素数,或者如果randint总是选择非素数,则while循环将会触及一个无限循环的可能性很小。永远不会结束。

所以这可能更短,更少麻烦:

import random
primes = [i for i in range(p,q) if isPrime(i)]
n = random.choice(primes)

这样做的另一个好处是,如果区间内没有素数,则不会出现死锁的可能性。如上所述,这可能会很慢,具体取决于范围,所以如果你提前缓存素数会更快:

# initialising primes
minPrime = 0
maxPrime = 1000
cached_primes = [i for i in range(minPrime,maxPrime) if isPrime(i)]

#elsewhere in the code
import random
n = random.choice([i for i in cached_primes if p<i<q])

同样,进一步优化是可能的,但非常依赖于您的实际代码......并且您知道他们对过早优化的看法。

答案 1 :(得分:1)

这是一个用python编写的脚本,用于在两个给定整数之间生成n个随机素数:


import numpy as np

def getRandomPrimeInteger(bounds):

    for i in range(bounds.__len__()-1):
        if bounds[i + 1] > bounds[i]:
            x = bounds[i] + np.random.randint(bounds[i+1]-bounds[i])
            if isPrime(x):
                return x

        else:
            if isPrime(bounds[i]):
                return bounds[i]

        if isPrime(bounds[i + 1]):
            return bounds[i + 1]

    newBounds = [0 for i in range(2*bounds.__len__() - 1)]
    newBounds[0] = bounds[0]
    for i in range(1, bounds.__len__()):
        newBounds[2*i-1] = int((bounds[i-1] + bounds[i])/2)
        newBounds[2*i] = bounds[i]

    return getRandomPrimeInteger(newBounds)

def isPrime(x):
    count = 0
    for i in range(int(x/2)):
        if x % (i+1) == 0:
            count = count+1
    return count == 1



#ex: get 50 random prime integers between 100 and 10000:
bounds = [100, 10000]
for i in range(50):
    x = getRandomPrimeInteger(bounds)
    print(x)

答案 2 :(得分:0)

因此,如果你可以使用迭代器以随机顺序从p到q给出整数(没有替换),那将会很棒。我一直无法找到办法。以下将给出该范围内的随机整数,并将跳过已经测试过的任何内容。

import random
fail = False
tested = set([])
n = random.randint(p,q)
while not isPrime(n):
    tested.add(n)
    if len(tested) == p-q+1:
        fail = True
        break
    while n in s:
        n = random.randint(p,q)

if fail:
    print 'I failed'
else:
    print n, ' is prime'

这样做的一大优点是,如果说你测试的范围只是(14,15),你的代码就会永远运行。如果存在这样的素数,则保证该代码产生答案,并告诉您如果不存在这样的素数则不存在。你显然可以使它更紧凑,但我试图显示逻辑。

答案 3 :(得分:-1)

next(i for i in itertools.imap(lambda x: random.randint(p,q)|1,itertools.count()) if isPrime(i))

这从itertools.count()开始 - 这给出了无限集。

通过itertools.imap()将每个数字映射到范围内的新随机数。 imap就像map,但是返回一个迭代器,而不是一个列表 - 我们不想生成一个无限随机数的列表!

然后,找到第一个匹配的号码,然后返回。

即使p和q相距很远,也能有效地工作 - 例如1和10 ** 30,生成完整列表不会做!

顺便说一下,这并不比上面的代码更有效,并且一目了然更难理解 - 请考虑下一个程序员必须阅读你的代码,然后就像你一样在上面做了。当你忘记了这段代码应该做的事情时,程序员可能在六个月内成为你!

P.S - 实际上,您可能希望将count()替换为xrange(NOT range!),例如xrange((p-q)**1.5+20)不要超过那个尝试次数(在小范围和大范围的有限测试之间取得平衡,如果成功则失败的概率不超过1/2%),否则,如同在另一篇文章,你可能会永远循环。

PPS - 改进:将random.randint(p,q)替换为random.randint(p,q)|1 - 这使代码效率提高了两倍,但消除了结果为2的可能性。