簡體   English   中英

素數代碼的優化

[英]Optimization of prime number code

這是我在python中的代碼,用於計算小於給定數字的素數之和。
我還能做些什么來優化它?

import math
primes = [2,]                      #primes store the prime numbers



for i in xrange(3,20000,2):                    #i is the test number
    x = math.sqrt(i)
    isprime = True
    for j in primes:               #j is the devider. only primes are used as deviders
        if j <= x:
            if i%j == 0:
                    isprime = False
                    break


    if isprime:
        primes.append(i,)


print sum (primes,)

您可以使用一種名為Sieve of Eratosthenes的不同算法它會更快但需要更多內存。 保留一組標志,表示每個數字是否為素數,並且對於每個新素數集,它對於該素數的所有倍數都為零。

N = 10000

# initialize an array of flags
is_prime = [1 for num in xrange(N)]
is_prime[0] = 0 # this is because indexing starts at zero
is_prime[1] = 0 # one is not a prime, but don't mark all of its multiples!

def set_prime(num):
    "num is a prime; set all of its multiples in is_prime to zero"
    for x in xrange(num*2, N, num):
        is_prime[x] = 0

# iterate over all integers up to N and update the is_prime array accordingly
for num in xrange(N):
    if is_prime[num] == 1:
        set_prime(num)

primes = [num for num in xrange(N) if is_prime[num]]

如果你使用一個有效的位數組,你實際上可以為相當大的N做這個,例如在這個例子中 (在頁面上向下滾動,你會找到一個Sieve of Eratosthenes的例子)。

您可以優化的另一件事是將sqrt計算移到內部循環之外。 畢竟, i通過它保持不變,所以沒有必要每次重新計算sqrt(i)

primes = primes + (i,)非常昂貴。 它復制循環每次傳遞的每個元素,將優雅的動態編程解決方案轉換為O(N 2 )算法。 改為使用列表:

primes = [2]
...
    primes.append(i)

另外,在傳遞sqrt(i)之后提前退出循環。 並且,由於保證在運行素數列表的末尾之前傳遞sqrt(i),因此就地更新列表而不是存儲isprime以供以后使用:

...
if j > math.sqrt(i):
    primes.append(i)
    break
if i%j == 0:
    break
...

最后,盡管這與性能無關,但使用范圍而不是while時更加Pythonic:

for i in range(3, 10000, 2):
    ...

只是另一個代碼而不使用任何導入:

#This will check n, if it is prime, it will return n, if not, it will return 0
def get_primes(n):
    if n < 2:
        return 0
    i = 2
    while True:
        if i * i > n:
            return n
        if n % i == 0:
            return 0
        i += 1

#this will sum up every prime number up to n
def sum_primes(n):
    if n < 2:
        return 0
    i, s = 2, 0
    while i < n:
        s += get_primes(i)
        i += 1
    return s

n = 1000000
print sum_primes(n)

編輯:在受到影響時刪除了一些愚蠢

所有用於查找素數的強力型算法,無論效率如何,隨着上限的增加將變得非常昂貴。 測試素數的啟發式方法實際上可以節省大量計算。 既定的可分性規則可以“一目了然”地消除大多數非素數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM