какое математическое решето ты знаешь
Факторизация чисел и методы решета. Часть I
В работе рассматривается традиционный подход, который автором в ряде статей критикуется.
Здесь я воздержусь от критики, и направлю свои усилия на разъяснение сложных моментов в традиционном подходе. Весь арсенал существующих методов не решает задачу факторизации в принципе, так как почти все решеточные и другие алгоритмы построены на жесткой связи и зависимости времени их выполнения от разрядности факторизуемого числа N. Но замечу, что у чисел имеются и другие свойства кроме разрядности, которые можно использовать в алгоритмах факторизации.
Оценки сложности — эвристические опираются на рассуждения ограниченные авторским пониманием проблемы. Пора бы уже понять, что факторизация чисел в глубоком тупике, а математикам (не только им) пересмотреть свое отношение к проблеме и создать новые модели.
Простая идея факторизации целого нечетного числа N исторически — состоит в поиске пары квадратов чисел разной четности, разность которых кратна kN, при k =1 разложение успешно реализуется так как в этом случае сразу получаем произведение двух скобок c сомножителями N. При k>1 случаются тривиальные разложения.
Таким образом, проблема факторизации преобразуется в проблему поиска подходящих квадратов чисел. Понимали эти факты многие математики, но П. Ферма первым в 1643 году реализовал идею поиска таких квадратов в алгоритме, названном его именем. Перепишем иначе приведенное соотношение .
Если разность слева от равенства не равна квадрату, то изменяя х, можно подобрать другой квадрат, чтобы и справа получался квадрат. Практически все нынешние алгоритмы используют эту идею (поиска пары квадратов), но судя по результатам, похоже, что идея себя исчерпала.
Предпосылки и возможности
Криптография с открытым ключом (асимметрические криптосистемы) ныне стала уже повседневностью, хотя совсем небольшой временной период (в историческом плане) отделяет нас от момента ее открытия. К основным ее отличиям от симметричной криптографии следует в первую очередь отнести возможность использования для передачи (шифрованных текстов (ШТ), других сообщений) незащищенных каналов в сетях информационного обмена, цифровую подпись, аутентификацию.
Математической основой этих фактов и явлений служат:
— односторонняя (однонаправленная) функция;
— односторонняя функция с лазейкой (с секретом).
Определение. Функция f: X → Y называется односторонней, если существует эффективный алгоритм ее вычисления при любом Х, но не существует такого алгоритма для вычисления обратной к ней функции.
Определение. Функция f: X → Y называется односторонней с секретом (с лазейкой, потайным ходом, trapdoor), если при наличии некоторой дополнительной информации (ключа) возможен эффективный алгоритм ее обращения. Под эффективным алгоритмом понимают полиномиальный в отличие от экспоненциального.
Математикам давно знакома проблема факторизации и они ищут пути ее эффективного решения. К основным достижениям (результатам) математики в области факторизации чисел следует отнести следующее:
— метод Евклида отыскания наибольшего общего делителя (НОД), в котором для пары чисел b и а, если они составные, но взаимно простые, НОД (а, b)=1. Но если эти числа имеют общий делитель, то алгоритм НОД находит больший из всех делитель d и НОД (а, b)=d.
— другой важный результат, которым располагает математика, состоит в том, что любое составное нечетное целое число N представимо разностью квадратов целых чисел разной четности или иначе . Второе соотношение допускает 1$» data-tex=»inline»/> целое. Эти результаты объединяются в одном соотношении .
— метод факторизации П. Ферма известен с 1643 года. Он находит наибольший множитель d числа N, не превосходящий . Метод требует О() арифметических операций и работает наиболее быстро, если множители p и q имеют близкие значения, т.е. когда их разность мала.
— решето Эратосфена.
Метод линейного решета (алгоритм LS)
Рихард Шрёппель (Richard Schroeppel), занимаясь проблемой факторизации чисел, предложил оригинальный алгоритм для генерации соотношений следующего вида .
На числовом интервале , где 0 0 для элементов факторной базы , которую образуют все простые числа, не превосходящие В, а также целое число –1. Далее рассматривается сравнение по модулю N
Допустим, что правая часть сравнения может быть представлена произведением и левая часть будет полным квадратом, если величины входят в произведение четное число раз ,
где рi простые числа из факторной базы S, а Δ – целое число, являющееся полным квадратом.
В такой ситуации сравнение с произведениями по модулю N соответствует сравнению с известным разложением v на множители из факторной базы. Целью в методе является получение таких соотношений числом, превышающим количество элементов в факторной базе.
Если это достигается, то возможно построить, используя алгоритм гауссова исключения, сравнение , обеспечивающее разложение N на множители.
Для формирования величин (a, b) существует эффективный способ, называемый решетом, поиска значений , при которых величины (a, b) раскладываются в произведение элементов факторной базы.
И сами величины (a, b) принимают небольшие значения. Значения ограничены и верна оценка:
Проверка делимости величины s (a, b) на простое число р для произвольных a, b∈ I сводится к проверке делимости на р величины
Это легко показывается. Пусть простое число р ∈ S делит значение величины s (a, b) при некоторых а. Но из равенства
следует, что для произвольных целых значений k, l.
Существенным недостатком метода является необходимость большого объема памяти, и отсутствие алгоритмического способа построения сравнений с известным разложением левой части в произведение множителей из факторной базы. Этот текст (компиляция) заимствован из разных публикаций, но практически не сопровождается моими комментариями. Для сравнения привожу другой текст о методе QS, но сопровождаю комментариями, которые, как я надеюсь, вносят понимание и ясность.
Квадратичное решето (QS)
Этот алгоритм (quadratic sieve-QS) предложен в 1981 году Карлом Померансом и почти 10 лет был лучшим (до предложенного в 1990 алгоритма SNFS (special number field sieve), обеспечившего разложение на множители 9-го числа П.Ферма (155 десятичных знаков)).
Возможности квадратичного решета ограничиваются разложением в сомножители чисел, с не более чем 110 десятичных цифр в их описании. Оценка сложности (эвристическая) алгоритма даже после многочисленных усовершенствований составляет арифметических операций.
Еще раз о поиске простых чисел
В заметке обсуждаются алгоритмы решета для поиска простых чисел. Мы подробно рассмотрим классическое решето Эратосфена, особенности его реализации на популярных языках программирования, параллелизацию и оптимизацию, а затем опишем более современное и быстрое решето Аткина. Если материал о решете Эратосфена предназначен в первую очередь уберечь новичков от регулярного хождения по граблям, то алгоритм решета Аткина ранее на Хабрахабре не описывался.
На снимке — скульптура абстрактного экспрессиониста Марка Ди Суверо «Решето Эратосфена», установленная в кампусе Стэнфорского университета
Введение
Напомним, что число называется простым, если оно имеет ровно два различных делителя: единицу и самого себя. Числа, имеющие большее число делителей, называются составными. Таким образом, если мы умеем раскладывать числа на множители, то мы умеем и проверять числа на простоту. Например, как-то так:
(Здесь и далее, если не оговорено иное, приводится JavaScript-подобный псевдокод)
Время работы такого теста, очевидно, есть O(n ½ ), т. е. растет экспоненциально относительно битовой длины n. Этот тест называется проверкой перебором делителей.
Довольно неожиданно, что существует ряд способов проверить простоту числа, не находя его делителей. Если полиномиальный алгоритм разложения на множители пока остается недостижимой мечтой (на чем и основана стойкость шифрования RSA), то разработанный в 2004 году тест на простоту AKS [1] отрабатывает за полиномиальное время. С различными эффективными тестами на простоту можно ознакомиться по [2].
Если теперь нам нужно найти все простые на достаточно широком интервале, то первым побуждением, наверное, будет протестировать каждое число из интервала индивидуально. К счастью, если у нас достаточно памяти, можно использовать более быстрые (и простые) алгоритмы решета. В этой статье мы обсудим два из них: классическое решето Эратосфена, известное еще древним грекам, и решето Аткина, наиболее совершенный современный алгоритм этого семейства.
Решето Эратосфена
Древнегреческий математик Эратосфен предложил следующий алгоритм для нахождения всех простых, не превосходящих данного числа n. Возьмем массив S длины n и заполним его единицами (пометим как невычеркнутые). Теперь будем последовательно просматривать элементы S[k], начиная с k = 2. Если S[k] = 1, то заполним нулями (вычеркнем или высеем) все последующие ячейки, номера которых кратны k. В результате получим массив, в котором ячейки содержат 1 тогда и только тогда, когда номер ячейки — простое число.
Реализация примет следующий вид:
Эффективность решета Эратосфена вызвана крайней простотой внутреннего цикла: он не содержит условных переходов, а также «тяжелых» операций вроде деления и умножения.
Оценим сложность алгоритма. Первое вычеркивание требует n/2 действий, второе — n/3, третье — n/5 и т. д. По формуле Мертенса
так что для решета Эратосфена потребуется O(n log log n) операций. Потребление памяти же составит O(n).
Оптимизация и параллелизация
Первую оптимизацию решета предложил сам Эратосфен: раз из всех четных чисел простым является только 2, то давайте сэкономим половину памяти и времени и будем выписывать и высеивать только нечетные числа. Реализация такой модификации алгоритма потребует лишь косметических изменений (код).
Наращивая шаг прогрессии и количество решет (например, при шаге прогрессии 210 нам понадобится 48 решет, что сэкономит еще 4% ресурсов) параллельно росту n, удается увеличить скорость алгоритма в log log n раз.
Сегментация
Не надо делать ситечки слишком маленькими, меньше тех же O(n ½-ε ) элементов. Так вы ничего не выиграете в асимптотике потребления памяти, но из-за накладных расходов начнете все сильнее терять в производительности.
Решето Эратосфена и однострочники
На Хабрахабре ранее публиковалась большая подборка алгоритмов Эратосфена в одну строчку на разных языках программирования (однострочники №10). Интересно, что все они на самом деле решетом Эратосфена не являются и реализуют намного более медленные алгоритмы.
Дело в том, что фильтрация множества по условию (например, на Ruby) или использование генераторных списков aka list comprehensions (например, на Haskell) вызывают как раз то, избежать чего призван алгоритм решета, а именно поэлементную проверку делимости. В результате сложность алгоритма возрастает по крайней мере до (это число фильтраций), умноженного на (минимальное число элементов фильтруемого множества), где — число простых, не превосходящих n, т. е. до O(n 3/2-ε ) действий.
Однострочник на Scala ближе к алгоритму Эратосфена тем, что избегает проверки на делимость. Однако сложность построения разности множеств пропорциональна размеру большего из них, так что в результате получаются те же O(n 3/2-ε ) операций.
Вообще решето Эратосфена тяжело эффективно реализовать в рамках функциональной парадигмы неизменяемых переменных. В случае, если функциональный язык (например, OСaml) позволяет, стоит нарушить нормы и завести изменяемый массив. В [3] обсуждается, как грамотно реализовать решето Эратосфена на Haskell при помощи техники ленивых вычеркиваний.
Решето Эратосфена и PHP
Запишем алгоритм Эратосфена на PHP. Получится примерно следующее:
Для решения этих проблем достаточно выбрать более подходящий тип данных — строку!
Теперь каждый элемент занимает ровно 1 байт, а время работы уменьшилось примерно втрое. Скрипт для измерения скорости.
Решето Аткина
В 1999 году Аткин и Бернштейн предложили новый метод высеивания составных чисел, получивший название решета Аткина. Он основан на следующей теореме.
Из элементарной теории чисел следует, что все простые, большие 3, имеют вид 12k+1 (случай 1), 12k+5 (снова 1), 12k+7 (случай 2) или 12k+11 (случай 3).
Для инициализации алгоритма заполним решето S нулями. Теперь для каждой пары (x, y), где , инкрементируем значения в ячейках S[4x 2 +y 2 ], S[3x 2 +y 2 ], а также, если x > y, то и в S[3x 2 −y 2 ]. В конце вычислений номера ячеек вида 6k±1, содержащие нечетные числа, — это или простые, или делятся на квадраты простых.
В качестве заключительного этапа пройдемся по предположительно простым номерам последовательно и вычеркнем кратные их квадратам.
Из описания видно, что сложность решета Аткина пропорциональна n, а не n log log n как у алгоритма Эратосфена.
Авторская, оптимизированная реализация на Си представлена в виде primegen, упрощенная версия — в Википедии. На Хабрахабре публиковалось решето Аткина на C#.
Как и в решете Эратосфена, при помощи wheel factorization и сегментации, можно снизить асимптотическую сложность в log log n раз, а потребление памяти — до O(n ½+o(1) ).
О логарифме логарифма
На самом деле множитель log log n растет крайне. медленно. Например, log log 10 10000 ≈ 10. Поэтому с практической точки зрения его можно полагать константой, а сложность алгоритма Эратосфена — линейной. Если только поиск простых не является ключевой функцией в вашем проекте, можно использовать базовый вариант решета Эратосфена (разве что сэкономьте на четных числах) и не комплексовать по этому поводу. Однако при поиске простых на больших интервалах (от 2 32 ) игра стоит свеч, оптимизации и решето Аткина могут ощутимо повысить производительность.
P. S. В комментариях напомнили про решето Сундарама. К сожалению, оно является лишь математической диковинкой и всегда уступает либо решетам Эратосфена и Аткина, либо проверке перебором делителей.
Решето Эратосфена
Решето Эратосфена
Одним из способов нахождения простых чисел, является метод, который называется «Решето Эратосфена». Онлайн разложение числа на простые множители можно провести здесь. Чтобы узнать что такое простые числа, просто прочитай эту статью.
Число называется простым, если оно делится только на 1 и само себя
Вроде бы всё просто. но недостатком является то, что нет математической формулы, которое позволяет убедиться, является число простым или нет.
Представьте число 191 587.Не существует формулы, чтобы определить, является ли оно простым!
Для этого нужно определить, есть ли в нем делители и, следовательно, составные.
Легко проверить, имеют ли первые несколько простых чисел (2, 3, 5, 7, 11) делители, используя критерии делимости. Но это не так просто для больших чисел.
Идея состоит в том, чтобы найти в таблице числа, кратные простым числам и отбросить их как составные. Числа, которые остались, будут простыми числами.
Решето Эратосфена останавливается, когда квадрат числа, которое мы тестируем, больше, чем последнее число в сетке (в нашем случае 100).
Поскольку 11 в квадрате равно 121 и 121 > 100, когда мы доберемся до числа 11, мы можем перестать смотреть.
Простые числа от 1 до 100 с решетом Эратосфена.
Начнем с размещения чисел от 1 до 100 в таблице, подобной этой.
Таким образом, очень легко создавать шаблоны, которые делают для нахождения простых чисел.
Сначала выделяем единицу, которая не является простым числом.
Далее мы ищем числа, кратные 2 и зачеркиваем их (оставляя 2, так как мы знаем, что он имеет только делители 1 и 2 и, следовательно, является простым). Все зачеркнутые числа будут составными.
Для наглядности я буду зачеркнутые составные числа делать светлым цветом.
Теперь из оставшихся чисел мы ищем кратные 3 и зачеркиваем их (кроме 3, поскольку оно простое). Простой способ сделать это, считая по три.
Делаем числа, кратные трем, светлым цветом и оставшихся чисел станет еще меньше.
Зачеркнутые числа снова делаем светлым цветом.
Давайте перейдем к коэффициентам 7 (число 6 = 2 x 3, а значит оно составное и мы уже нашли кратные 2 и 3). Мы не зачеркиваем 7, так как это простое число. Кратных семи всего в таблице осталось 3 числа — это 49, 77 и 91. Зачеркиваем их.
И опять же для наглядности изменяю цвет зачеркнутых чисел.
Должны ли мы искать кратные 8, 9 и 10? Поскольку эти числа составные и кратны числам, которые мы уже искали, мы можем перейти к цифре 11. Мы уже установили, что остановимся на цифре 11, так что это означает, что мы закончили!
Список простых чисел от 1 до 100
Поэтому мы можем определить, что числа, которые мы не зачеркнули или которые синего и красного цветов, являются простыми числами. Итак, теперь у нас есть список простых чисел от 1 до 100:
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89 и 97.
Видите, как легко с помощью этого метода искать простые числа!
Простые и составные числа, определения, примеры, таблица простых чисел, решето Эратосфена
В статье рассматриваются понятия простых и составных чисел. Даются определения таких чисел с примерами. Приводим доказательство того, что количество простых чисел неограниченно и произведем запись в таблицу простых чисел при помощи метода Эратосфена. Будут приведены доказательства того, является ли число простым или составным.
Простые и составные числа – определения и примеры
Простые и составные числа относят к целым положительным. Они обязательно должны быть больше единицы. Делители также подразделяют на простые и составные. Чтобы понимать понятие составных чисел, необходимо предварительно изучить понятия делителей и кратных.
Составными числами называют целые числа, которые больше единицы и имеют хотя бы три положительных делителя.
Единица не является ни простым ни составным числом. Она имеет только один положительный делитель, поэтому отличается от всех других положительных чисел. Все целые положительные числа называют натуральными, то есть используемые при счете.
Простые числа – это натуральные числа, имеющие только два положительных делителя.
Составное число – это натуральное число, имеющее более двух положительных делителей.
Натуральные числа, которые не являются простыми, называют составными.
Таблица простых чисел
Для того, чтобы было проще использовать простые числа, необходимо использовать таблицу:
Рассмотрим теорему, которая объясняет последнее утверждение.
Наименьший положительный и отличный от 1 делитель натурального числа, большего единицы, является простым числом.
Простых чисел бесконечно много.
Видно, что может быть найдено любое простое число среди любого количества заданных простых чисел. Отсюда следует, что простых чисел бесконечно много.
Решето Эратосфена
Данный способ неудобный и долгий. Таблицу составить можно, но придется потратить большое количество времени. Необходимо использовать признаки делимости, которые ускорят процесс нахождения делителей.
Перейдем к формулировке теоремы.
Данное число простое или составное?
Перед решением необходимо выяснять, является ли число простым или составным. Зачастую используются признаки делимости. Рассмотрим это на ниже приведенных примере.
Доказать что число 898989898989898989 является составным.
Ответ: 11723 является составным числом.