Каков наилучший подход к вычислению наибольшего простого множителя числа?
Я думаю, что наиболее эффективным будет следующее:
- Найти наименьшее простое число, которое делит чисто
- Проверьте, является ли результат деления простым
- Если нет, найдите следующий самый низкий
- Перейти к 2.
Я основываю это предположение на том, что легче вычислить малые простые факторы. Это правильно? Какие еще подходы я должен рассмотреть?
Редактировать: Теперь я понял, что мой подход бесполезен, если в игре более двух основных факторов, поскольку шаг 2 не выполняется, когда результат является продуктом двух других простых чисел, поэтому необходим рекурсивный алгоритм.
Отредактируйте еще раз: И теперь я понял, что это все еще работает, потому что последнее найденное простое число должно быть наибольшим, поэтому любое дальнейшее тестирование не простого результата из шага 2 приведет к меньшему простому числу.
algorithm
math
prime-factoring
Меркуцио
источник
источник
1.
найти любое число, которое делится четко (для i = 2 на int (sqr (num))),2.
разделить на это число (num = num / i) и повторять до тех пор, пока ничего не будет найдено в интервале 1.3.
num - это самый большой факторОтветы:
На самом деле есть несколько более эффективных способов найти факторы больших чисел (для более мелких пробное деление работает достаточно хорошо).
Один метод, который очень быстр, если входное число имеет два фактора, очень близких к его квадратному корню, известен как факторизация Ферма . Он использует тождество N = (a + b) (a - b) = a ^ 2 - b ^ 2 и прост для понимания и реализации. К сожалению это не очень быстро в целом.
Наиболее известным методом для вычисления чисел длиной до 100 цифр является квадратичное сито . В качестве бонуса, часть алгоритма легко выполняется с параллельной обработкой.
Еще один алгоритм, о котором я слышал, - это алгоритм Полларда Ро . Это не так эффективно, как Quadratic Sieve в целом, но, кажется, его легче реализовать.
Как только вы решили, как разделить число на два фактора, вот самый быстрый алгоритм, который я могу придумать, чтобы найти наибольший простой фактор числа:
Создайте очередь с приоритетами, в которой изначально хранится сам номер. На каждой итерации вы удаляете наибольшее число из очереди и пытаетесь разделить его на два фактора (конечно, не позволяя 1 быть одним из этих факторов). Если этот шаг не пройден, число простое, и у вас есть свой ответ! В противном случае вы добавляете два фактора в очередь и повторяете.
источник
Вот лучший алгоритм, который я знаю (в Python)
Вышеприведенный метод работает в
O(n)
худшем случае (когда вход является простым числом).РЕДАКТИРОВАТЬ:
Ниже приведена
O(sqrt(n))
версия, как предлагается в комментарии. Вот код, еще раз.источник
O(sqrt(n))
худшем случае» - нет, он работает вO(n)
худшем случае (например, когдаn
это простое число)Мой ответ основан на Триптихе , но значительно улучшается. Он основан на том факте, что за пределами 2 и 3 все простые числа имеют вид 6n-1 или 6n + 1.
Недавно я написал статью в блоге, объясняющую, как работает этот алгоритм.
Я бы рискнул, что метод, в котором нет необходимости в тесте на первичность (и нет конструкции сита), будет работать быстрее, чем тот, который его использует. Если это так, то это, вероятно, самый быстрый алгоритм здесь.
источник
while (multOfSix - 1 <= n)
Код JavaScript:
Пример использования:
Вот пример кода :
источник
Похоже на ответ @Triptych, но также отличается. В этом примере список или словарь не используется. Код написан на Ruby
источник
Все числа могут быть выражены как произведение простых чисел, например:
Вы можете найти их, просто начав с 2 и просто продолжая делить, пока результат не станет кратным вашему числу:
используя этот метод, вам не нужно фактически вычислять какие-либо простые числа: все они будут простыми числами, основываясь на том факте, что вы уже максимально разложили число со всеми предыдущими числами.
источник
currFactor = 3513642
, мы знаем, что 12345678987667 простое число, и должны вернуть его в качестве ответа. Вместо этого этот код будет продолжать перечисление до самого 12345678987667. Это на 3,513,642x медленнее, чем необходимо.источник
while
цикл будет проходить черезi
значения2,2,2,2,2,2,2,2,2,2,2,2, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5
. Всего 60 итераций. Но (10 ^ 12 + 39) будет (10 ^ 12 + 38) итераций,i=2,3,4,5,6,...,10^12+39
. Даже если 10 ^ 10 операций займет одну секунду, 10 ^ 12 займет 100 секунд. Но только 10 ^ 6 итераций действительно необходимы, и если 10 ^ 10 операций займет секунду, 10 ^ 6 займет 1/10000-й секунды.long n = 2*1000000000039L
? Работает ли он так быстро, как должен? (также, можете ли вы упростить свой код с помощьюreturn;
оператора?). (если вы хотите, чтобы я перестала подталкивать вас, просто скажите так;))Самое простое решение - это пара взаимно рекурсивных функций.
Первая функция генерирует все простые числа:
Вторая функция возвращает простые множители заданного числа
n
в порядке возрастания.n
.Наибольшим простым множителем
n
является последнее число, заданное второй функцией.Этот алгоритм требует отложенного списка или языка (или структуры данных) с семантикой вызова по требованию .
Для пояснения, вот одна (неэффективная) реализация вышеперечисленного в Haskell:
Чтобы сделать это быстрее, просто нужно быть более умным в определении того, какие числа являются простыми и / или факторами
n
, но алгоритм остается тем же.источник
Есть некоторые тесты по модулю, которые излишни, так как n никогда не может быть разделено на 6, если все факторы 2 и 3 были удалены. Вы можете разрешить только простые числа для i, что показано здесь в нескольких других ответах.
Вы могли бы на самом деле переплетать сито Эратосфена здесь:
Также смотрите этот вопрос .
источник
Я знаю, что это не быстрое решение. Размещение, как мы надеемся, облегчает понимание медленного решения.
источник
Итеративный подход Python, удаляющий все простые множители из числа
источник
Я использую алгоритм, который продолжает делить число на текущий фактор фактора.
Мое решение в Python 3:
Вход:
10
Выход:5
Вход:
600851475143
Выход:6857
источник
Вот моя попытка в C #. Последняя распечатка является наибольшим основным фактором числа. Я проверил, и это работает.
источник
источник
Вычисляет наибольший простой множитель числа, используя рекурсию в C ++. Работа кода объясняется ниже:
источник
Вот мой подход к быстрому вычислению наибольшего простого множителя. Он основан на том факте, что модифицированные
x
не содержат не простых факторов. Чтобы достичь этого, мы делим,x
как только фактор найден. Тогда остается только вернуть самый большой фактор. Это было бы уже премьер.Код (Haskell):
источник
Следующий алгоритм C ++ не самый лучший, но он работает для чисел до миллиарда и довольно быстрый
источник
Нашел это решение в сети "Джеймс Ван"
источник
Главный фактор с использованием сита:
источник
Мне кажется, что шаг № 2 данного алгоритма не будет таким уж эффективным подходом. У вас нет разумных ожиданий, что оно простое.
Кроме того, предыдущий ответ, предполагающий сито Эратосфена, совершенно неверен. Я просто написал две программы с множителем 123456789. Одна была основана на сите, другая - на следующем:
Эта версия была в 90 раз быстрее, чем сито.
Дело в том, что на современных процессорах тип операции имеет гораздо меньшее значение, чем количество операций, не говоря уже о том, что приведенный выше алгоритм может выполняться в кеше, а Sieve - нет. Сито использует много операций, вычеркивая все составные числа.
Также обратите внимание, что мои факторы разделения по мере их выявления уменьшают пространство, которое необходимо проверить.
источник
Сначала вычислите список, хранящий простые числа, например, 2 3 5 7 11 13 ...
Каждый раз, когда вы делите число на простые числа, используйте реализацию от Triptych, но итерируйте этот список простых чисел, а не натуральные целые числа.
источник
С Java:
Для
int
значений:Для
long
значений:источник
Вероятно, это не всегда быстрее, но более оптимистично в отношении того, что вы найдете большой простой делитель:
N
твой номерreturn(N)
Sqrt(N)
N is divisible by Prime
тогдаReturn(Prime)
Редактировать: На шаге 3 вы можете использовать Сито Эратосфена или Сито Аткинса или все, что вам нравится, но само по себе сито не найдет вас самым большим главным фактором. (Вот почему я не выбрал бы пост SQLMenace в качестве официального ответа ...)
источник
Я думаю, что было бы хорошо хранить где-нибудь все возможные простые числа, меньшие, чем n, и просто перебирать их, чтобы найти самый большой делитель. Вы можете получить простые числа от prime-numbers.org .
Конечно, я предполагаю, что ваш номер не слишком большой :)
источник
Не самый быстрый, но это работает!
источник
Вот та же функция @ Triptych, что и генератор, которая также немного упрощена.
максимальное простое число может быть найдено с помощью:
и список факторов, найденных с использованием:
источник
источник