Python でエラトステネスのふるいを書いてみた


エラトステネスのふるい(sieve of Eratosthenes)は、
ある数が素数であるか判別するためのアルゴリズムだ。


関数 sieve_of_Eratosthenes_v1 は、
「調べる数」を、「調べる数/2」以下の全ての整数で割って、
割りきれなければ素数とする。
10000までの素数を調べた時の実行時間(10回の平均):0.962354秒


関数 sieve_of_Eratosthenes_v2 は、
「調べる数」を、「素数」で割って、
割りきれなければ素数とする。
10000までの素数を調べた時の実行時間(10回の平均):0.098287秒


v2 は v1 より10倍速い。いいね! ←自己満足


get_prime_numbers.py

def sieve_of_Eratosthenes_v1(p_terminal_number) :
    """
    The purpse of this function is get prime numbers
    using algorithm 'The sieve of Eratosthenes'.
    broken number: from '2' to terminal number. 
    divided number: from '2' to 'broken number / 2'. 
    When broken number can't be divided by divided number,
    broken number is prime number.
    """

    broken_number = range(p_terminal_number + 1)
    prime_numbers = [ ]
    for broken in broken_number[ 2: ] :
        last_check = broken / 2
        divided_number = range(last_check+1)
        for divided in divided_number[ 2: ]:
            if broken % divided == 0 :
                break
            else :
                pass
        else:
            prime_numbers.append(broken)
    return prime_numbers


def sieve_of_Eratosthenes_v2(p_terminal_number) :
    """
    The purpse of this function is get prime numbers
    using algorithm 'The sieve of Eratosthenes'.
    broken number: from '3' to terminal number. 
    divided number: prime numbers.
    When broken number can't be divided by prime numbers,
    broken number is prime number.
    """

    broken_number = range(p_terminal_number + 1)
#  set initial prime number
    prime_numbers = [2]
    for broken in broken_number[ 3: ] :
        for prime in prime_numbers :
            if broken % prime == 0 :
                break
            else :
                pass
        else :
            prime_numbers.append(broken)
    return prime_numbers

ちなみに実行時間はこんな感じで調べた。
measure.py

def measure_run_time(p_function_name, p_arg01) :
    import time

    time_history = [ ]
# call fucntion 10 times
    loop_count = 10
    while loop_count:
        start_time = time.clock( )
 # call function of parameter function name
        p_function_name(p_arg01)
        end_time = time.clock( )
        run_time = end_time - start_time
        time_history.append(run_time)
        loop_count = loop_count - 1
    time_history.sort( )
    for run_time in time_history:
        print 'run time   %f second' % (run_time)

    total = 0
 # get average without best result and worst result
    for run_time in time_history[1:9]:
        total = total + run_time
    else:
        average = total / 8
        print '%f' % average

if __name__ == '__main__' :
    import sys
    import get_prime_numbers
    measure_run_time(get_prime_numbers.sieve_of_Eratosthenes_v1, 10000)
    measure_run_time(get_prime_numbers.sieve_of_Eratosthenes_v2, 10000)