Каков наилучший алгоритм для проверки, является ли число простым?
просто пример того, что я ищу: я мог бы представить каждое нечетное число с битом, например, для данного диапазона чисел (1, 10], начинается с 3:
1110
следующий словарь можно сжать более правильно? Я мог бы выделить кратные пять с некоторой работой, но числа, которые заканчиваются 1, 3, 7 или 9, должны быть там в массиве битов. Надеюсь, это прояснит то, что я хочу.
Я ищу лучший алгоритм, чтобы проверить, является ли число простым, т. е. булева функция:
bool isprime(number);
Я хотел бы знать лучший алгоритм для реализации этой функции. Естественно, была бы структура данных, которую я мог бы запросить. Я определите лучший алгоритм, чтобы быть алгоритмом, который создает структуру данных с наименьшим потреблением памяти для диапазона (1, N], где N-константа.
19 ответов:
есть много способов сделать тест на примитивность.
на самом деле нет структуры данных для запроса. Если у вас есть много чисел для тестирования, вы, вероятно, должны запустить вероятностный тест так как они быстрее, а затем следовать за ним с детерминированный тест чтобы убедиться, что число простым.
вы должны знать, что математика за самые быстрые алгоритмы не для слабонервных.
самый быстрый алгоритм для общего премьер-тестирования АКС. Статья в Википедии описывает его по длине и ссылкам на оригинальную статью.
если вы хотите найти большие числа, посмотрите на простые числа, которые имеют специальные формы, такие как простые числа Мерсенна.
алгоритм, который я обычно реализую (легко понять и код), выглядит следующим образом (в Python):
def isprime(n): """Returns True if n is prime.""" if n == 2: return True if n == 3: return True if n % 2 == 0: return False if n % 3 == 0: return False i = 5 w = 2 while i * i <= n: if n % i == 0: return False i += w w = 6 - w return Trueэто вариант классического . Он использует тот факт, что простое число (кроме 2 и 3) имеет форму
6k - 1или6k + 1и смотрит только на делители эту форму.иногда, если я действительно хочу скорость и диапазон ограничен, я реализую псевдо-простой тест на основе маленькая теорема Ферма. Если я действительно хочу больше скорости(т. е. вообще избегать алгоритма O(sqrt (N))), я предварительно вычисляю ложные срабатывания (см. Кармайкл числа) и выполните двоичный поиск. Это самый быстрый тест, который я когда-либо реализованный, единственный недостаток заключается в том, что диапазон ограничен.
лучший метод, на мой взгляд, это использовать то, что прошло раньше.
есть списки первых
Nпростые числа в интернете сNпротяженностью не менее пятьдесят миллионов. Загрузите файлы и используйте их, это, вероятно, будет намного быстрее, чем любой другой метод, который вы придумаете.Если вы хотите реальный алгоритм для создания собственных простых чисел, Википедия имеет все виды хороших вещей на простых числах здесь, включая ссылки на различные методы для этого, и премьер-тестирование здесь, как вероятностные, так и быстро-детерминированные методы.
bool isPrime(int n) { // Corner cases if (n <= 1) return false; if (n <= 3) return true; // This is checked so that we can skip // middle five numbers in below loop if (n%2 == 0 || n%3 == 0) return false; for (int i=5; i*i<=n; i=i+6) if (n%i == 0 || n%(i+2) == 0) return false; return true; } this is just c++ implementation of above AKS algorithm
В Python 3:
def is_prime(a): if a < 2: return False elif a!=2 and a % 2 == 0: return False else: return all (a % i for i in range(3, int(a**0.5)+1) )объяснение: Простое число-число, делящееся только на себя и 1. Экс: 2,3,5,7...
1) Если a Если " а " меньше 2, то это не простое число.
2) elif a!=2 и % 2 == 0: Если " а " делится на 2, то это определенно не простое число. Но если a=2, мы не хотим оценивать это, поскольку это простое число. Отсюда и состояние!=2
3) вернуть все (a % i для i в диапазоне (3, int (a0.5)+1) ):** Сначала посмотрите, что делает команда all () в python. Начиная с 3 делим "а" до его квадратного корня (а**0,5). Если "a" делится, то вывод будет ложным. Почему квадратный корень? Допустим, a=16. Квадратный корень из 16 = 4. Нам не нужно оценивать до 15. Нам нужно только проверить до 4, чтобы сказать, что это не простое число.
дополнительные: Цикл для нахождения всех простых чисел в диапазоне.
for i in range(1,100): if is_prime(i): print("{} is a prime number".format(i) )
слишком поздно для вечеринки, но надеюсь, что это поможет. Это актуально, если вы ищете большие простые числа:
для проверки больших нечетных чисел необходимо использовать тест ферма и / или тест Миллера-Рабина.
эти тесты используют модульное возведение в степень, что довольно дорого, для
nбиты возведения в степень вам нужно по крайней мереnбольшое умножение int иnбольшой инт подразделения. Это означает, что сложность модульного возведения в степень равна O (n3).Так что прежде чем с помощью большой пушки, вам нужно сделать несколько пробных делений. Но не делайте это наивно, есть способ сделать их быстро. Сначала умножьте столько простых чисел вместе, сколько вписывается в слова, которые вы используете для больших целых чисел. Если вы используете 32-битные слова, умножьте 3*5*7*11*13*17*19*23*29=3234846615 и вычислите наибольший общий делитель с числом, которое вы проверяете, используя евклидов алгоритм. После первого шага число уменьшается ниже размера слова и продолжить алгоритм без выполнения завершите большие целочисленные деления. Если GCD != 1, это означает, что одно из простых чисел, которые вы умножили вместе, делит число, поэтому у вас есть доказательство, что оно не простое. Затем продолжить 31*37*41*43*47 = 95041567, и так далее.
после того, как вы протестировали несколько сотен (или тысяч) простых чисел таким образом, вы можете сделать 40 раундов теста Миллера-Рабина, чтобы подтвердить, что число простое, после 40 раундов вы можете быть уверены, что число простое, есть только 2^-80 шанс, что это не так (скорее всего, ваше оборудование неправильное срабатывание...).
у меня есть основная функция, которая работает до (2^61)-1 здесь:
from math import sqrt def isprime(num): num > 1 and return all(num % x for x in range(2, int(sqrt(num)+1)))объяснение:
The
all()функция может быть переопределена следующим образом:def all(variables): for element in variables: if not element: return False return TrueThe
all()функция просто проходит через ряд bools / numbers и возвращаетFalseесли он видит 0 илиFalse.The
sqrt()функция просто делает квадратный корень ряда.для пример:
>>> from math import sqrt >>> sqrt(9) >>> 3 >>> sqrt(100) >>> 10The
num % xчасть возвращает остаток числа / x.наконец,
range(2, int(sqrt(num)))означает, что он создаст список это начинается на 2 и заканчивается наint(sqrt(num)+1)для получения дополнительной информации о диапазоне, взгляните на это сайт!
The
num > 1часть просто проверяет, если переменнаяnumбольше 1, потому что 1 и 0 не считаются простыми числа.надеюсь, это помогло:)
В Python:
def is_prime(n): return not any(n % p == 0 for p in range(2, int(math.sqrt(n)) + 1))более прямое преобразование из математического формализма в Python будет использовать все(n % p != 0... ), но это требует строгой оценки всех значений P. Элемент не любой версия может завершиться рано, если найдено истинное значение.
лучший алгоритм для простых чисел javascript
function isPrime(num) { if (num <= 1) return false; else if (num <= 3) return true; else if (num % 2 == 0 || num % 3 == 0) return false; var i = 5; while (i * i <= num) { if (num % i == 0 || num % (i + 2) == 0) return false; i += 6; } return true }
аналогичная идея алгоритма AKS, который был упомянут
public static boolean isPrime(int n) { if(n == 2 || n == 3) return true; if((n & 1 ) == 0 || n % 3 == 0) return false; int limit = (int)Math.sqrt(n) + 1; for(int i = 5, w = 2; i <= limit; i += w, w = 6 - w) { if(n % i == 0) return false; numChecks++; } return true; }
чтобы узнать, является ли число или числа в диапазоне/простыми.
#!usr/bin/python3 def prime_check(*args): for arg in args: if arg > 1: # prime numbers are greater than 1 for i in range(2,arg): # check for factors if(arg % i) == 0: print(arg,"is not Prime") print(i,"times",arg//i,"is",arg) break else: print(arg,"is Prime") # if input number is less than # or equal to 1, it is not prime else: print(arg,"is not Prime") return # Calling Now prime_check(*list(range(101))) # This will check all the numbers in range 0 to 100 prime_check(#anynumber) # Put any number while calling it will check.
myInp=int(input("Enter a number: ")) if myInp==1: print("The number {} is neither a prime not composite no".format(myInp)) elif myInp>1: for i in range(2,myInp//2+1): if myInp%i==0: print("The Number {} is not a prime no".format(myInp)) print("Because",i,"times",myInp//i,"is",myInp) break else: print("The Number {} is a prime no".format(myInp)) else: print("Alas the no {} is a not a prime no".format(myInp))
можно использовать sympy.
import sympy sympy.ntheory.primetest.isprime(33393939393929292929292911111111) TrueС sympy документы. Первый шаг-поиск тривиальных факторов, которые, если они найдены, позволяют быстро вернуться. Далее, если сито достаточно большое, используйте разделительный поиск на сите. Для малых чисел выполняется набор детерминированных тестов Миллера-Рабина с базисами, которые, как известно, не имеют контрпримеров в своем диапазоне. Наконец, если число больше 2^64, выполняется сильный тест BPSW. Хотя это вероятный простой тест, и мы считаем, что контрпримеры существуют, нет известных контрпримеров
вы могли бы попробовать нечто подобное.
def main(): try: user_in = int(input("Enter a number to determine whether the number is prime or not: ")) except ValueError: print() print("You must enter a number!") print() return list_range = list(range(2,user_in+1)) divisor_list = [] for number in list_range: if user_in%number==0: divisor_list.append(number) if len(divisor_list) < 2: print(user_in, "is a prime number!") return else: print(user_in, "is not a prime number!") return main()
маленькая память? Это не самый маленький, но шаг в правильном направлении.
class PrimeDictionary { BitArray bits; public PrimeDictionary(int n) { bits = new BitArray(n + 1); for (int i = 0; 2 * i + 3 <= n; i++) { bits.Set(i, CheckPrimality(2 * i + 3)); } } public PrimeDictionary(IEnumerable<int> primes) { bits = new BitArray(primes.Max()); foreach(var prime in primes.Where(p => p != 2)) { bits.Set((prime - 3) / 2, true); } } public bool IsPrime(int k) { if (k == 2) { return true; } if (k % 2 == 0) { return false; } return bits[(k - 3) / 2]; } }конечно, вы должны указать определение
CheckPrimality.
Я думаю, что одним из самых быстрых является мой метод, который я сделал.
void prime(long long int number) { // Establishing Variables long long int i = 5; int w = 2; const long long int lim = sqrt(number); // Gets 2 and 3 out of the way if (number == 1) { cout << number << " is hard to classify. \n"; return; } if (number == 2) { cout << number << " is Prime. \n"; return; } if (number == 3) { cout << number << " is Prime. \n"; return; } // Tests Odd Ball Factors if (number % 2 == 0) { cout << number << " is not Prime. \n"; return; } if (number % 3 == 0) { cout << number << " is not Prime. \n"; return; } while (i <= lim) { if (number % i == 0) { cout << number << " is not Prime. \n"; return; } // Tests Number i = i + w; // Increments number w = 6 - i; // We already tested 2 and 3 // So this removes testing multepules of this } cout << number << " is Prime. \n"; return; }
public static boolean isPrime(int number) { if(number < 2) return false; else if(number == 2 || number == 3) return true; else { for(int i=2;i<=number/2;i++) if(number%i == 0) return false; else if(i==number/2) return true; } return false; }
Comments