Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的随机素数_Python_Random_Generator_List Comprehension_Primes - Fatal编程技术网

python中的随机素数

python中的随机素数,python,random,generator,list-comprehension,primes,Python,Random,Generator,List Comprehension,Primes,我现在有↓ 设置为myrandprime(p,q)函数。有没有办法通过像genexp或listcomp这样的东西来压缩这一点?以下是我的功能: n = randint(p, q) while not isPrime(n): n = randint(p, q) 最好只生成素数列表,然后从该行中进行选择。 同样,对于您的代码,它命中无限循环的可能性很小,如果间隔中没有素数,或者如果randint始终选择非素数,那么while循环将永远不会结束 所以这可能更短,也不那么麻烦: import

我现在有↓ 设置为my
randprime(p,q)
函数。有没有办法通过像genexplistcomp这样的东西来压缩这一点?以下是我的功能:

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

最好只生成素数列表,然后从该行中进行选择。 同样,对于您的代码,它命中无限循环的可能性很小,如果间隔中没有素数,或者如果
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])
#初始化素数
minPrime=0
maxPrime=1000
cached_primes=[i代表范围内的i(minPrime,maxPrime),如果isPrime(i)]
#守则的其他地方
随机输入
n=random.choice([i表示缓存的\u素数中的i,如果p
这是从itertools.count()开始的-这提供了一个无限集

每个数字都被itertools.imap()映射到范围内的一个新随机数。imap类似于map,但返回的是迭代器,而不是列表-我们不想生成有限个随机数的列表

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

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

顺便说一句,这并不比上面的代码更有效,而且一眼就看不懂——请考虑让下一个程序员阅读你的代码,然后像上面那样去做。当你忘记了这段代码应该做什么的时候,六个月后的程序员可能就是你了

注意-在实践中,您可能希望用xrange(非range!)替换count(),例如
xrange((p-q)**1.5+20)
以不超过该尝试次数(在小范围和大范围的有限测试之间进行平衡,如果成功,失败的概率不超过1/2%),否则,正如另一篇文章中所建议的,您可能会永远循环


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

因此,如果您可以使用迭代器以随机顺序(无需替换)给出从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),您的代码将永远运行。如果存在这样一个素数,此代码将保证生成一个答案,如果不存在这样一个素数,则会告诉您答案是不存在的。您显然可以使其更紧凑,但我正在尝试显示逻辑。

以下是一个用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)


似乎最好生成一个介于
p
q
之间的素数列表,然后从该列表中随机选择一个。您可以通过将最低位设置为1来增加一个数字被素数的几率,从而使其成为奇数-只有一个偶数素数,即2。事实上,除2和3之外的所有素数都是ei下面的一个,或者六的倍数上面的一个。我讨厌有人在没有说明原因的情况下对一个问题进行向下投票,因为如果OP不知道问题出在哪里,他就无法修复它。@HunterMcMillen,这取决于p&q的大小。对于大数字,这会更有效。另外,如果你在做数字筛选(生成素数的最简单方法),那么你需要从1开始。各位,这个问题缺乏具体性,这里的很多来回都是由这个问题引起的。你能不能责怪这个问题而不是其他回答者?如果p和q的顺序是10**10,这可能是一个非常糟糕的主意,如果你在考虑加密,这是一个合理的尝试。我猜如果有在
p
q
之间的素数肯定会死锁。好吧,他们可能会缓存
isPrime
检查,或者有一个预构建的列表可以使用。@legostrmtropr-不一定。当使用大素数时(例如,用于RSA加密),通常的方法是检查较小的数字,然后使用统计方法-请参阅(因为2048位素数的完整测试将花费数年时间)-在素数上的每次测试运行都会成功,而在非素数上的每次测试运行都有50%的机会显示该数字为非素数。确定您想要的概率有多低,并运行适当数量的测试。人们只是对加密和疯狂的大数做出了疯狂的假设。这可能是大学一年级的编程任务ion.是的,但如果给定一个没有素数的范围,我的将完成,如果给定一个只有几个素数的范围,我的运行时间将大大缩短。OP中的代码有3行,但如果p和q之间没有素数,它将死锁,因此它是不安全的。是我,我投票否决了你,因为你的答案,虽然引入了一些有用的东西,但恰恰相反关于被问到的问题-
是否有任何方法可以浓缩这一点
。我承认那部分不是我的。这不是我答案的基础,只是一个脚注。欢迎你将我的代码作为脚注(或想法)纳入你的答案中@AMADANONInc.Fine-你的代码只有一行,但它的字符数仍然是原始代码的2倍,需要导入itertools,并且无法解决错误。这是压缩的吗?去掉我的代码中消除错误的部分,我的代码基本上是相同的长度(以字符为单位)就像你的一样。@legostrmtroopr但如果整数的范围非常大(通常是在人们需要时),它将不会在合理的时间内完成

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)