2016-03-30 3 views
4

Я занимался проблемой 7 в Project Euler, когда у меня возникла проблема. Мой код длился долго. Вот мой код.Как ускорить процесс поиска?

def Problem7(): 
    num = 0 
    p = 0 
    while p < 10002 : 
     prime = True 
     for i in range(2,num): 
      if (num%i==0): 
       prime = False 
     if prime: 
      print(num) 
      p = p + 1 
     num = num + 1 
Problem7() 

Как это сделать быстрее? Есть ли другой способ?

+1

это python2.x или python3.x? Для python2.x очень быстрая оптимизация - это переход от 'range' к' xrange'. – mgilson

+3

В этой реализации есть несколько вещей, которые не имеют большого смысла: (1) При поиске делителей вы можете остановить квадратный корень от числа, которое вы тестируете. Если что-то большее, чем дивизор, то должен быть соответствующий меньший делитель. (2) Как только вы найдете делитель, выйдите из цикла (т. Е. 'Break'). Зачем искать что-то, как только вы его нашли? (3) Единственное четное число, которое нужно проверить в качестве делителя, равно 2. После этого вы можете пропустить все четные числа. Возможны другие улучшения скорости, но те, которые я перечисляю, совершенно тривиальны. –

+0

Чтобы сделать это быстрее, используйте более эффективный алгоритм, такой как [Сито Эратосфена] (https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes). Разделение каждого отдельного номера на все числа до того, как он займет очень много времени для больших простых чисел. –

ответ

3

Вы должны сделать свою жизнь проще и распечатать счетчик посещений в конце, что я подозреваю, что переменная p хранит.

Как отмечено в комментариях, вы можете устранить множество вычислений с помощью более разумного алгоритма.

1: Проверьте, если число четное (NUM% 2) (если да, то не простое)

2: В то время как делитель меньше или равен квадратному корню и загрунтовать == Правда, тест делителей

3: Если еще не простой, прирост на 2, так что вы только проверить нечетные числа (Все эвены были проверены с NUM% 2)

Если вы хотите, чтобы получить супер эффективными, каждый номер, который не является простым, по меньшей мере один простой фактор, поэтому вы можете сохранить каждое начальное число, которое вы найдете в массиве, и проверить только до самого высокого в массиве ... Но это много дополнительного кода, что не обязательно к этой проблеме. Используя вышеприведенную логику, я нашел первые 10000 простых чисел в течение нескольких секунд на тестовом прогоне.

Если вы думаете о номере 100, ваша логика проверяет 99 возможных делителей. Вышеуказанные логические тесты только 2 останавливаются. Худший случай перехода к квадратному корню будет только 2,3,5,7,9 ... 5 расчетов вместо 99.

1

Я использовал следующий метод, чтобы проверить, является ли число простым (работает в 0m0.612s):

import math 

def is_prime(num): 
    if num == 0 or num == 1: 
     return False 
    if num == 2: 
     return True 
    temp = 2 
    while temp < math.sqrt(num) + 1: 
     if num % temp == 0: 
      return False 
     temp += 1 

    return True 
Смежные вопросы