计算素数

时间:2010-09-17 23:56:11

标签: python math

我现在正在做麻省理工学院的开放课程,而且已经完成了第二次任务,我觉得这让我感冒了。 http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-00-introduction-to-computer-science-and-programming-fall-2008/assignments/pset1a.pdf

它的具体内容是写一些可以计算出第1000个素数的东西。我们只知道print,==,=,1 =,if,else,elif,while,%, - ,+,*,/,命令我认为。我们还不知道导入库。

我对它如何工作的想法是取一个奇数并尝试将其除以3,4,5,6,7,8,9并且如果%n!= 0,则在NumberofPrimes中添加一个数字变量从11开始作为测试的基础,并在NumberofPrimes的基础上为它赋予基础值4,虽然我不知道这是否正确,因为我不知道如何显示第1000个素数

我关闭了吗?

最新版本如下:

##calculate the 1000th prime number
potprime = 3
numberofprime = 1
cycle = if potprime%3 = 0:
            break
        if potpimre%4 = 0:
            break
        if potprime%5 = 0:
            break
        if potprime%6 = 0:
            break
        if potprime%7 = 0:
            break
        if potprime%8 = 0:
            break
        if potprime%9 = 0:
            break
        numberofprime + 1
        potprime + 1

if potprime%2 == 0:
    potprime = potprime + 1
if potprime != 0:
    cycle

我到底哪里错了?一步一步地带我走过去。我真的很想学习它,虽然我觉得我只是被冷落在这里。

在这一点上,对我来说,看看如何做一个合适的人而不是这样做会更有益。我已经工作了3个小时而且无处可去。如果有人有解决方案,我会非常乐意看到它并尝试从中学习。

9 个答案:

答案 0 :(得分:6)

看起来我迟到了

如果一个数字不能被任何素数整除,那么这个数字本身就是一个素数,这是非常直截了当的。您可以使用此事实来最小化分割数。

为此您需要维护一个素数列表。并且对于每个数字,只尝试除以列表中已有的素数。为了进一步优化它,您可以丢弃超过要测试的数字的平方根的所有素数。您需要为此导入sqrt()函数。

例如,如果您在1001上进行测试,请尝试使用3,5,7,11,13,17,19,23,29和31进行测试。这应该足够了。也永远不要试图找出偶数是素数。所以基本上如果你测试一个奇数n,那么在那个测试之后的下一个数字:(n + 2)

已测试以下代码。第1000个素数是7919.不是一个很大的数字!!

代码可能如下:

from math import sqrt

primeList = [2]
num = 3
isPrime = 1

while len(primeList) < 1000:
    sqrtNum = sqrt(num)

    # test by dividing with only prime numbers
    for primeNumber in primeList:

        # skip testing with prime numbers greater than square root of number
        if num % primeNumber == 0:
            isPrime = 0
            break
        if primeNumber > sqrtNum:
            break

    if isPrime == 1:
        primeList.append(num)
    else:
        isPrime = 1

    #skip even numbers
    num += 2

# print 1000th prime number
print primeList[999]

答案 1 :(得分:3)

以下代码是,但由于1000确实是一个小索引,它在几分之一秒内解决了您的问题(它只使用了您应该知道的原语) :

primesFound = 0
number = 1

while primesFound < 1000:
    number = number + 1          # start from 2

    # test for primality
    divisor = 2
    numberIsPrime = True
    while divisor*divisor <= number:   # while divisor <= sqrt(number)
        if number % divisor == 0:
            numberIsPrime = False
            break
        divisor = divisor + 1

    # found one?
    if numberIsPrime:
        primesFound = primesFound + 1

print number

您可以测试解决方案here。 现在你应该找到一个更有效的解决方案,进行优化,并且可能会选择100万个素数......

答案 2 :(得分:2)

首先,我很确定在Python中,如果你想要一个if语句测试是否A = B,你需要使用==运算符,而不是=。

另一方面,你的算法会将数字143视为素数,即使143 = 11 * 13

您需要跟踪已计算的所有素数 - 将它们添加到数组中。使用该数组来确定您正在测试的新数字是否为素数。

答案 3 :(得分:2)

在我看来,在决定小孩池太深的时候,你正在跳入深渊。在覆盖基本语法之后,素数项目将在大多数开始编程类中分配2或3。而不是帮助你使用算法(那里有许多好的)我会建议你在编写长程序之前尝试用 python shell 学习语法,因为调试一行是比调试整个程序更容易。以下是您实际运行的方式:

count = 4
n = 10                        #I'm starting you at 10 because your method 
                              #says that 2, 3, 5, and 7 are not prime
d = [2, 3, 4, 5, 6, 7, 8, 9]  #a list containing the ints you were dividing by

def cycle(n):                 #This is how you define a function
    for i in d:               #i will be each value in the list d
        if not n%i:           #this is equal to if n%i == 0
            return 0          #not prime (well, according to this anyway)
    return 1                  #prime

while count < 1000:
    count += cycle(n)         #adds the return from cycle to count
    n += 1

print n - 1

答案仍然不正确,因为这不是如何测试素数。但是知道一点语法至少会得到错误的答案,这比许多追溯更好。

(另外,我知道列表,for循环和函数不在你说你知道的事情列表中。)

答案 4 :(得分:2)

此答案的代码只能简化为:

prime_count = 1
start_number = 2
number_to_check = 2
while prime_count <= 1000:
    result = number_to_check % start_number

    if result > 0:
        start_number +=1

    elif result == 0:
        if start_number == number_to_check:
            print (number_to_check)
            number_to_check +=1
            prime_count +=1
            start_number =2
        else:
            number_to_check +=1
            start_number = 2

答案 5 :(得分:1)

要回答您的后续问题,'如何跟踪所有素数?

这样做的一种方法是制作清单。

primeList = [] # initializes a list

然后,每当您测试一个数字是否为素数时,请将该数字添加到primeList

您可以使用'append'功能来完成此操作。

primeList.append( potprime )  # adds each prime number to that list

然后你会看到列表中填满数字,所以在前三个素数之后它看起来像这样:

>>> primeList
[11, 13, 17]

答案 6 :(得分:0)

你的数学失败了。素数是一个具有2个除数的数字:1和它本身。你没有测试素数的数字。

答案 7 :(得分:0)

我这很迟,但也许我的回答对某人有用。我在麻省理工学院做同样的开放课程,这是我提出的解决方案。它返回正确的第1000个素数和正确的第100,000个素数以及我测试过的其他各种素数。我认为这是一个正确的解决方案(我认为不是最有效的解决方案,但我认为这是一个有效的解决方案)。

#Initialise some variables
candidate = 1 
prime_counter = 1 

while prime_counter < 1000: 
    test = 2 
    candidate = candidate + 2

    # While there is a remainder the number is potentially prime.
    while candidate%test > 0:
        test = test + 1

    # No remainder and test = candidate means candidate is prime.
    if candidate == test: 
        prime_counter = prime_counter + 1

print "The 1000th prime is: " + str(candidate)

当我在那里时,我接着完成了作业的第二部分。问题提出如下:

“数理论中有一个可爱的结果表明,对于足够大的n,小于n的素数的乘积小于或等于e ^ n,并且随着n的增长,这变得紧张(也就是说,随着n的增长,素数与e ^ n的乘积之比接近于1)。 计算大量素数的乘积可能导致数量非常大, 这可能会导致我们的计算出现问题。 (我们将谈论如何 计算机在该术语稍后处理数字。)因此,我们可以通过将对数应用于该猜想的两个部分,将一组素数的乘积转换为素数的对数之和。在这种情况下,上面的猜想减少到声称的总和 小于n的所有素数的对数小于n,并且当n增长时,该和与n的比率接近于1.“

这是我的解决方案。我打印每1000个素数到第10,000个素数的结果。

from math import *

#Initialise some variables
candidate = 1 
prime_counter = 1 
sum_logs = log(2)

while prime_counter < 10000: 
    test = 2 
    candidate = candidate + 2
    # While there is a remainder the number is potentially prime.
    while candidate%test > 0:
        test = test + 1
    # No remainder and test = candidate means candidate is prime.
    if candidate == test: 
        prime_counter = prime_counter + 1
    # If the number is prime add its log to the sum of logs.
        sum_logs = sum_logs + log(candidate)
    if prime_counter%1000 == 0:
        # For every 1000th prime print the result.
        print sum_logs," ",candidate," ",sum_logs/candidate
print "The 10000th prime is: " + str(candidate)

干杯,

阿德里安

答案 8 :(得分:0)

我在采访中提出了这个解决方案,但我没有得到这份工作:(它的迭代次数比上述解决方案少1/100:

from math import *

MAX_IDX=1000
MAX_IDX-=1

num_iter=0

l_pirme_list=[3]
candidate=l_pirme_list[0]
prime_counter=1

while prime_counter < MAX_IDX: 
    candidate+=2
    #Cut the binary number in half. This is quite faster than sqrt()
    bin_candidate=format(candidate, "2b")
    max_prime_search=int(bin_candidate[:len(bin_candidate)/2+1],2)+1
    # max_prime_search=sqrt(candidate)+1

    candidate_is_prime=1
    for prime_item in l_pirme_list:
        num_iter+=1

        if candidate % prime_item==0:
            candidate_is_prime=0
            break

        elif prime_item > max_prime_search:
            candidate_is_prime=1
            break


    if candidate_is_prime:
        prime_counter+=1
        l_pirme_list.append(candidate)

l_pirme_list.insert(0,2)
print "number iterations=", num_iter
print l_pirme_list[MAX_IDX]