Изменения

Перейти к: навигация, поиск

Разложение на множители (факторизация)

559 байт убрано, 19:17, 4 сентября 2022
м
rollbackEdits.php mass rollback
{{Определение | definition=
'''Факторизация''' (англ. ''factorization'') — представление объекта в виде произведения других объектов.
}}
{{Определение | definition=
'''Разложение на множители''', или '''Факторизация целых чисел''' (англ. ''integer factorization'') — представление числа в виде [[Основная теорема арифметикиНатуральные числа#Основная теорема арифметики#Собственно теорема | произведения его множителей]].
}}
== Перебор делителей==
{{Определение | definition=
'''Перебор делителей'' ' (англ. ''Trial division'') — алгоритм для факторизации или тестирования простоты числа путем полного перебора всех возможных потенциальных делителей.
}}
 == Перебор делителей = Наивная реализация O(англ. ''Trial division''n)====== Наивная реализация [[Основная теорема арифметики#Основная теорема арифметики#Собственно теорема | Основная теорема арифметики]], вкупе с утверждением, что <tex>y</tex> не делит <tex>x</tex> нацело: <tex>\forall x, y \in \mathbb{N}~~x<y \Longrightarrow</tex> <tex>O\left(n\dfrac{x}{y} < 1 \right)</tex> ===, позволяют нам ограничить пространство поиска делителей числа <tex>number</tex> интервалом <tex>[2;number]</tex>.
==== Основная идея ====
[[Основная теорема арифметики#Основная теорема арифметики#Собственно теорема | Основная теорема арифметики]], в купе с утверждениемЗаметим, что если <tex>number</tex> = <tex>\forall x, y prod p_i = p_1 \cdot p_2 \cdot \ldots \cdot p_{j-1} \in cdot p_j \mathbbcdot p_{Nj+1}~~x<y \Longrightarrowcdot \ldots \cdot p_n</tex> {{Acronym|, то <tex>\left( \dfrac{xnumber}{yp_j} < 1 \right)= \prod\limits_{i \ne j} p_i = p_1 \cdot p_2 \cdot \ldots \cdot p_{j-1} \cdot p_{j+1} \cdot \ldots \cdot p_n</tex>.е. y не делит x нацело}}Таким образом, позволяют нам ограничить пространство поиска делителей числа мы можем делить <tex>\mathtt{number}</tex> интервалом на его делители (множители) последовательно и в любом порядке. Тогда будем хранить <tex>[2; curNum \colon curNum = \mathttdfrac{number}]{\prod result_i}</tex>— произведение оставшихся множителей.
Заметим, что если <tex>\mathtt{number} = \prod p_i = p_1 * p_2 * \dots * p_{j-1} * p_j * p_{j+1} * \dots * p_n</tex>, то <tex>\left(\dfrac{\mathtt{number}}{p_i}\right) = \prod\limits_{i \ne j} p_i = p_1 * p_2 * \dots * p_{j-1} * p_{j+1} * \dots * p_n</tex>. Таким образом, мы можем делить <tex>\mathtt{number}</tex> на его {{Acronym|делители|множители}} последовательно и в любом порядке. Тогда будем хранить <tex>\mathtt{curNum} \colon \mathtt{curNum} * \prod \mathtt{result_i} =\mathtt{number}</tex> — произведение оставшихся множителей.
==== Псевдокод нахождения простых множителей ====
Алгоритм Так как простых множителей не может быть больше, чем <tex>n</tex>, а в худшем случае (когда число простое, и на каждое итерации <tex>probe</tex> увеличивается на <tex>1</tex>) он работает за <tex>O(kn)</tex>, где k — количество простых множителейто, следовательно, алгоритм работает за <tex>O(n)</tex>.
'''function''' getMultipliers(number: '''int'''): '''vector<int>'''
probe = 2
'''while''' curNum <tex>\ne</tex> 1
'''if''' curNum '''mod''' probe <tex>\ne 0\, </tex>0
<font color=green>// проверены все множители из [2; probe]</font>
probe++
=== Улучшенная реализация <tex>O(\sqrt{n})</tex> ===
==== Основная идея ====
Из определения: <tex>\sqrt{n} * \cdot \sqrt{n} = n</tex>. Логично, что:
{|
|-align="center"
|rowspan="2"| <tex>\bigg\{</tex>
|<tex>x * \cdot y = number</tex>
|rowspan="2"| <tex>\Longrightarrow x > \sqrt{number}</tex>
|-align="center"
==== Псевдокод ====
'''function''' getDividers</tex>(number: '''int'''): '''vector<int>'''
result = '''vector<int>'''
'''for''' probe = 2 '''to''' <tex>\sqrt{number}</tex> <font color=green>// <--- обновляем верхнюю границу перебора</font> '''if''' number '''mod ''' probe = 0
result += [probe]
result += [number / probe] <font color=green>// <--- записываем сопряженный делитель</font>
'''return''' result
=== Проверка числа на простоту. Множители ===Алгоритм можно переделать для нахождения простых чисел. Число будет простым, если у него не окажется {{Acronym|множителей|(и делителей}} ) кроме <tex>1 </tex> (алгоритмы не проверяют делимость на <tex>1</tex>) и самого числа (улучшенная реализация опускает этот делитель). Исключительный случай: <tex>number = 2</tex>.
Вообще говоря, представленный выше алгоритм <tex>\mathrm{getMultipliers}</tex> ищет простые множители. Чтобы получить разложения на множители необходимо реализовать [[Генерация комбинаторных объектов в лексикографическом порядке|перебор разбиений]] мультимножества простых множителей на подмножества, тогда, перемножив элементы подмножеств, мы получим множители.
== Предподсчет ==
{{main|Решето Эратосфена}}
<font color=green>// возвращает только дополнительный массив</font>
'''function''' sieveOfEratosthenes(n: '''int'''): '''int'''[n+ 1] result = [n+ 1] result[n] = n
<font color=green>// выбираем следующий простой делитель</font>
'''for''' i = 2 '''to''' <tex>\sqrt{n}</tex> '''if''' result[i] <tex>\ne</tex> ''null''= 0 <font color=green>// {{Acronym|записываем |в этой реализации и переписываем тоже}}делитель в элементы массива,
// соответствующие числа которых делятся нацело</font>
shuttle = <tex>i^2</tex>
// делением предыдущего на простой делитель из решета</font>
curNum = number
'''while''' sieve[curNum] <tex>\ne</tex> ''null''1 result += sieve[sieveNumcurNum]
curNum /= sieve[curNum]
result += [curNum]
'''return''' result
 
== Источники информации ==
* Маврин П.Ю. — Лекция по алгоритмам над простыми числами (2016)
* [https://ru.wikipedia.org/wiki/Простое_число https://ru.wikipedia.org/wiki/Простое_число]
== См. также ==
*[[Основная теорема арифметики]]
*[[Дискретная математика, алгоритмы и структуры данных#Комбинаторика | Комбинаторика]]
 
== Источники информации ==
* Маврин П.Ю. — Лекция по алгоритмам над простыми числами (2016)
* [https://ru.wikipedia.org/wiki/Простое_число https://ru.wikipedia.org/wiki/Простое_число]
[[Категория: Алгоритмы алгебры и теории чисел]]
[[Категория: Теория чисел]]
1632
правки

Навигация