简体   繁体   English

素数代码的优化

[英]Optimization of prime number code

This is my code in python for calculation of sum of prime numbers less than a given number. 这是我在python中的代码,用于计算小于给定数字的素数之和。
What more can I do to optimize it? 我还能做些什么来优化它?

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,)

You can use a different algorithm called the Sieve of Eratosthenes which will be faster but take more memory. 您可以使用一种名为Sieve of Eratosthenes的不同算法它会更快但需要更多内存。 Keep an array of flags, signifying whether each number is a prime or not, and for each new prime set it to zero for all multiples of that prime. 保留一组标志,表示每个数字是否为素数,并且对于每个新素数集,它对于该素数的所有倍数都为零。

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]]

You can actually do this for pretty large N if you use an efficient bit array, such as in this example (scroll down on the page and you'll find a Sieve of Eratosthenes example). 如果你使用一个有效的位数组,你实际上可以为相当大的N做这个,例如在这个例子中 (在页面上向下滚动,你会找到一个Sieve of Eratosthenes的例子)。

Another thing you could optimize is move the sqrt computation outside the inner loop. 您可以优化的另一件事是将sqrt计算移到内部循环之外。 After all, i stays constant through it, so there's no need to recompute sqrt(i) every time. 毕竟, i通过它保持不变,所以没有必要每次重新计算sqrt(i)

primes = primes + (i,) is very expensive. primes = primes + (i,)非常昂贵。 It copies every element on every pass of the loop, converting your elegant dynamic programming solution into an O(N 2 ) algorithm. 它复制循环每次传递的每个元素,将优雅的动态编程解决方案转换为O(N 2 )算法。 Use lists instead: 改为使用列表:

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

Also, exit the loop early after passing sqrt(i). 另外,在传递sqrt(i)之后提前退出循环。 And, since you are guaranteed to pass sqrt(i) before running off the end of the list of primes, update the list in-place rather than storing isprime for later consumption: 并且,由于保证在运行素数列表的末尾之前传递sqrt(i),因此就地更新列表而不是存储isprime以供以后使用:

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

Finally, though this has nothing to do with performance, it is more Pythonic to use range instead of while: 最后,尽管这与性能无关,但使用范围而不是while时更加Pythonic:

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

Just another code without using any imports: 只是另一个代码而不使用任何导入:

#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)

EDIT: removed some silliness while under influence 编辑:在受到影响时删除了一些愚蠢

All brute-force type algorithms for finding prime numbers, no matter how efficient, will become drastically expensive as the upper bound increases. 所有用于查找素数的强力型算法,无论效率如何,随着上限的增加将变得非常昂贵。 A heuristic approach to testing for primeness can actually save a lot of computation. 测试素数的启发式方法实际上可以节省大量计算。 Established divisibility rules can eliminate most non-primes "at-a-glance". 既定的可分性规则可以“一目了然”地消除大多数非素数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM