SoFunction
Updated on 2024-11-17

6 ways to compute prime numbers in python

Because to learn to write infiltration tools, these days are on python programming basics class, listening to me doze off, after all, I have learned it before. Finally sherry teacher left homework, one of the questions is this:

Topic: write python program to find prime numbers between 10-30.

It's so simple, I'll give a straight answer:

Prime = [11, 13, 17, 19, 23, 29]
print(Prime)

Output results:

[11, 13, 17, 19, 23, 29]

Of course, this would certainly result in a public execution by Ms. Sherry in the next class, so it's better to write an algorithm based on what you learned in class.

1. Exhaustive method

Think back to the class learned variables, lists, loops and other things, sherry teacher also personally demonstrated multiple dead loop is how to get out of (the teacher is slippery hands or business is not skilled ah), so we still need to think carefully not to repeat the same mistakes.

Idea: First construct a loop that iterates over all eligible natural numbers, then one by one verify that they are prime, and finally list the eligible primes.

# The first exhaustive method that was coded was simple and brutal, just performance pulling across.
# P = factor, N = natural number
import time
t0 = ()  # Start time
Min = 10  # Range minimum
Max = 30  # Range maximum
Result = []  # Results
for N in range(Min, Max):  # Give the natural numbers an iteration
    for P in range(2, N):
        if (N % P == 0):  # Determine if there are factors
            break  # With a factor it's not prime, break out of the loop #
    else:
        (N)
print('Calculation', Min, 'to', Max, 'Between prime numbers')
print(Min, 'to', Max, Sequence of primes between ':', Result)
print(Min, 'to', Max, The number of primes between ':', len(Result))
print('Calculation time consumed:', () - t0, 'Seconds')

Execution results (computation elapsed time is added at the end):

By this point the homework was done. I then finished a couple of other problems and realized I was bored, so I cut back to try and get something going. With this amount of computation, 0 seconds is really a bit low, so I might as well take this opportunity to bake the laptop's performance, so I'll just add a couple of zeros to the Min and Max values. try 100000-200000.

It's embarrassing, it's stuck straight away, the code is a bit of a pull across, not my style at all. Poured a cup of coffee and finally ran it.

This is too much, there must be something wrong, the code I wrote in C a long time ago wasn't that slow as I remember. Anyway, I've got the weekend free, so I might as well take a closer look at it.

2. Function (CV) method

To broaden my mind a bit, I decided to borrow some code from the big boys. I've heard that functions are a good thing, so I CV'd two of them.

One function determines primes, the other seeks all primes in the range, and putting them together, this is what it looks like:

# Learned it online, customized two functions, but it gets stuck with slightly larger values.
import time
t0 = ()
Min = 100000  # Range minimum
Max = 200000  # Range maximum
def is_prime(n): return 0 not in [n % i for i in range(2, n//2+1)]  # Determine whether a number is prime or not
def gen_prime(a, b): return [n for n in range(
    a, b+1) if 0 not in [n % i for i in range(2, n//2+1)]]  # Prime numbers in the output range
print('Calculation', Min, 'to', Max, 'Between prime numbers')
print(Min, 'to', Max, Sequence of primes between ':', gen_prime(Min, Max))
print('Calculation time consumed:', () - t0, 'Seconds')

Slightly altered, still 100,000-200,000, let's try it.

Well, as soon as it runs the fan starts whining and the CPU is baking. It seems the CV method doesn't work either. After a long bake, this time the result is even worse than the last time, more than 300 seconds, these two functions are still essentially an exhaustive method, it seems that this road is not going to work either.

3. Exhaustive reform

We can analyze the code of the exhaustive method to see if there is any improvement. First of all, through the nine years of compulsory education to master the knowledge of mathematics, we know that only 2 of the primes are even, so the calculation can be ignored the even numbers, only the odd numbers, the workload is immediately halved! Secondly, when determining whether N is prime by factoring P, if P is large enough, say when PxP>=N, then the loop that follows is actually repeated meaninglessly. Because assuming PxQ>=N, then one of P and Q must be less than sqrt(N), and it's just a matter of calculating the case where P<=sqrt(N).

Because 2 as the only even number, sandwiched inside the loop is troublesome to deal with, so put in the beginning to deal with away. The final code is as follows:

# Optimized code with fewer pointless loops is much faster than before.
import time
t0 = ()
Min = 100000  # Range minimum
Max = 200000  # Range maximum
Prime = [2, 3]  # List of prime numbers
Result = []  # Results
Loop = 0  # Calculate the number of cycles
if Min <= 2:
    (2)
if Min <= 3:
    (3)  # Get rid of the troublesome even number of two first #
for N in range(5, Max, 2):
    for P in range(3, int(N**0.5)+2, 2):  # Calculated only up to the root N
        Loop += 1
        if (N % P == 0):
            break
    else:
        (N)
        if N > Min:
            (N)
print('Calculation', Min, 'to', Max, 'Between prime numbers')
print(Min, 'to', Max, Sequence of primes between ':', Result)
print(Min, 'to', Max, The number of primes between ':', len(Result))
print('Number of cycles:', Loop)
print('Calculation time consumed:', () - t0, 'Seconds')

The amount of code is more, but the effect is still obvious, 100000-200000 is only 0.4 seconds, I don't know how much faster, it seems like we are on the right track. I decided to add more to 1000000-500000000 to see if it would hold up. Because the output is too much the console will get stuck, so change it and only output the last prime number.

It took a total of 64 seconds, so it still seems like a bit of a chore.

4. Exhaustive magic

Let's analyze this a little more, what if the factors we use to determine, instead of using a list of odd numbers, we use the primes inside the generated Prime list, since there are far fewer primes than there are odd numbers, so the second loop would be less work? Could try it. But because of this change, you need to add some judgment statements into it, so the time saved is more limited.

# Don't look at this code as long, but it won't get stuck running up to 10 million, and it's fast.
import time
t0 = ()
Min = 1000000  # Range minimum
Max = 5000000  # Range maximum
Prime = [2, 3]  # List of prime numbers
Result = []  # Results
Loop = 0  # Calculate the number of cycles
if Min <= 2:
    (2)
if Min <= 3:
    (3)
for N in range(5, Max, 2):
    M = int(N**0.5)  # The upper limit is the root sign N
    for P in range(len(Prime)):  # Iterate through Prime, the list of primes #
        Loop += 1
        L = Prime[P+1]
        if (N % L == 0):
            break
        elif L >= M:  # The upper limit is greater than the root N, determine the prime number and jump out of the loop
            (N)
            if N > Min:
                (N)
            break
print('Calculation', Min, 'to', Max, 'Between prime numbers')
print('The last prime number:', Result[-1])
print(Min, 'to', Max, The number of primes between ':', len(Result))
print('Number of cycles:', Loop)
print('Calculation time consumed:', () - t0, 'Seconds')

Or 1,000,000-5,000,000 and try again.

This time it took 22 seconds, which is a big chunk of time again, but there doesn't seem to be much room for improvement anymore, and it feels like the exhaustive method has run its course and needs new ideas.

5. Echidna sieve method

In fact, in middle school math we learned the Echidna sieve method: if P is a prime number, then multiples of N greater than P must not be prime. If we eliminate all the combinations, then all the remaining numbers are prime. We can generate a list to store whether a number is prime or not, initially prime, and each time we come up with a prime number, we mark all its multiples as combinations.

# The speed has taken off.
import time
t0 = ()
Min = 1000000  # Range minimum
Max = 2000000  # Range maximum
Loop = 0  # Calculate the number of cycles
Result = []  # Results
Natural = [True for P in range(Max)]  # The list of natural numbers is marked True
for P in range(2, Max):
    if Natural[P]:  # If the flag is True, it's prime.
        if P >= Min:
            (P)  # Add primes within range
        for N in range(P*2, Max, P):   # Change the marking of multiples of prime numbers to False
            Loop += 1
            Natural[N] = False
print('Calculation', Min, 'to', Max, 'Between prime numbers')
print('The last prime number:', Result[-1])
print(Min, 'to', Max, The number of primes between ':', len(Result))
print('Number of cycles:', Loop)
print('Calculation time consumed:', () - t0, 'Seconds')

1.6 seconds, more than 10 times faster than the most advanced exhaustive method, is a triumph of math. Try 1-50,000,000 again.

It's great that it only takes 20 seconds. Because of the nature of the sieve method, ignoring the effect of memory, the higher the value, the faster the later instead.

6. Euler sieve method

We can carefully analyze, the above Echidna sieve method in the final mark, or overcounting something, N will repeat the mark False, such as 77, both a multiple of 7 and a multiple of 11, so it will be marked twice, followed by a large ensemble of numbers will repeat the mark many times, a waste of arithmetic, so the marking of the exclusion of ensembles. The other thing is that when P*N is greater than Max, the later calculations are no longer meaningful and should also be jumped out. Excluding these repetitive actions is the Euler sieve method, also called linear sieve.

# Final version, optimized for many details.
import time
t0 = ()
Min = 1  # Range minimum
Max = 50000000  # Range maximum
Loop = 0  # Calculate the number of cycles
Prime = [2]
Result = []  # Results
if Min <= 2:
    (2)
Limit = int(Max/3)+1
Natural = [True for P in range(Max+1)]  # The list of natural numbers is marked True
for P in range(3, Max+1, 2):
    if Natural[P]:  # If the flag is True, it's prime.
        (P)
        if P >= Min:
            (P)
    if P > Limit:  # No need to sift beyond Limit, just continue #
        continue
    for N in Prime:   # Change the marking of multiples of prime numbers to False
        Loop += 1
        if P*N > Max:  # Over Max it's meaningless, just break.
            break
        Natural[P * N] = False
        if P % N == 0:  # Determine if a number is a combination
            break
print('Calculation', Min, 'to', Max, 'Between prime numbers')
print('The last prime number:', Result[-1])
print(Min, 'to', Max, The number of primes between ':', len(Result))
print('Number of cycles:', Loop)
print('Calculation time consumed:', () - t0, 'Seconds')

(Updated this code because the previous version was indented incorrectly)

The same conditions took 11.46 seconds. This is due to the extra list and a few lines of judgment statements, and the interpreted nature of python, so it's not actually several times faster, but it's still about a 50% improvement in overall efficiency.

To this point this article on python to calculate the prime number of 6 ways to introduce this article, more related python to calculate the prime number of content please search for my previous articles or continue to browse the following related articles I hope you will support me more in the future!