Метод Кронекера: различия между версиями

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
[отпатрулированная версия][отпатрулированная версия]
Содержимое удалено Содержимое добавлено
Описание метода: оформление
 
(не показано 40 промежуточных версий 20 участников)
Строка 1: Строка 1:
''Метод Кронекера'' — метод разложения [[многочлен]]а с [[целые числа|целыми]] коэффициентами на [[неприводимый многочлен|неприводимые]] множители над кольцом целых чисел; предложен в 1882 [[Кронекер, Леопольд|Кронекером]].
'''''Метод Кронекера''''' — метод разложения [[многочлен]]а с [[целые числа|целыми]] коэффициентами на [[неприводимый многочлен|неприводимые]] множители над [[кольцо (математика)|кольцом]] целых чисел; предложен в 1882 [[Кронекер, Леопольд|Кронекером]].


Алгоритм Кронекера находит для данного многочлена <math>F(x)</math> многочлен <math>f(x)</math>, такой, что <math>F(x)</math> делится на <math>f(x)</math>,
Алгоритм Кронекера находит для данного многочлена <math>F(x)</math> многочлен <math>f(x)</math>, такой, что <math>F(x)</math> делится на <math>f(x)</math>, или доказывает, что такого многочлена нет.
или доказывает, что такого многочлена нет.


== Описание метода ==
== Описание метода ==
Алгоритм Кронекера основан на следующих соображениях:
Алгоритм Кронекера основан на следующих соображениях:


# Если степень многочлена <math>F</math> равна <math>n</math>, то степень хотя бы одного множителя <math>f</math> многочлена не превосходит <math>\left\lfloor {n\over 2} \right\rfloor</math> ;
# Если степень многочлена <math>F</math> равна <math>n</math>, то степень хотя бы одного множителя <math>f</math> многочлена не превосходит <math>\left\lfloor {n\over 2} \right\rfloor</math> ;
# Значения как <math>F</math> , так и <math>f</math> в целых точках — целые числа, причем <math>f(i</math>) делит <math>F(i)</math> для любого целого <math>i</math>;
# Значения как <math>F</math> , так и <math>f</math> в целых точках — целые числа, причем <math>f(i</math>) делит <math>F(i)</math> для любого целого <math>i</math>;
# При фиксированном <math>i</math>, если <math>F(i)</math> не равно 0, то <math>f(i)</math> может принимать только конечное множество значений, состоящее из делителей числа <math>F(i)</math>;
# При фиксированном <math>i</math>, если <math>F(i)</math> не равно 0, то <math>f(i)</math> может принимать только конечное множество значений, состоящее из делителей числа <math>F(i)</math>;
# Коэффициенты многочлена <math>f</math> однозначно восстанавливаются по его значениям в точке.
# Коэффициенты многочлена <math>f</math> однозначно восстанавливаются по его значениям в точке.


Таким образом, для <math>f</math> получается конечное число возможностей; непосредственным делением проверяем, получили ли делитель многочлена <math>F</math>.
Таким образом, для <math>f</math> получается конечное число возможностей; непосредственным делением проверяем, получили ли делитель многочлена <math>F</math>.
Строка 16: Строка 15:
Строгое Изложение:
Строгое Изложение:


Рассмотрим <math>f(x) \in \mathbb{Z}[x]</math> — многочлен степени <math>n</math>. Пусть <math>f(x)</math> приводим над <math>\mathbb{Z}</math>. Тогда <math>\! f(x) = g(x)h(x)</math> и один из двух многочленов <math>g(x)</math> и <math>h(x)</math> имеет степень не выше <math>n/2</math>. Пусть без ограничения общности <math>\operatorname{deg} \, g(x) \leqslant n/2</math>. Тогда <math>\forall a \in \mathbb{Z} \; h(a) \in \mathbb{Z}</math>, следовательно <math>f(a) \vdots g(a)</math>. Рассмотрим <math>m=n/2+1</math> различных целых чисел <math>a_i, i=\overline{1,m}</math> таких, что <math>f(a_i)\not=0</math>. Поскольку числа <math>\!f(a_i)</math> имеют конечное количество целых делителей, можно перебрать всевозможные наборы значений для <math>\!g(a_i)</math>. По каждому такому набору построим интерполяционный многочлен <math>\!g^*(x)</math> степени <math>m-1=n/2</math>. Если теперь <math>f(x)\vdots g^*(x)</math>, к многочленам <math>\!g^*(x)</math> и <math>\frac{f(x)}{g^*(x)}</math> можно применить тот же метод, и так до тех пор, пока все множители не станут неприводимыми. В противном случае, если <math>\forall g^*(x) \ f(x)\!\!\not\vdots g^*(x)</math>, многочлен <math>f(x)</math> уже является неприводимым.
Рассмотрим <math>f(x) \in \mathbb{Z}[x]</math> — многочлен степени <math>n</math>. Пусть <math>f(x)</math> приводим над <math>\mathbb{Z}</math>. Тогда <math>f(x) = g(x)h(x)</math> и один из двух многочленов <math>g(x)</math> и <math>h(x)</math> имеет степень не выше <math>n/2</math>. Пусть без ограничения общности <math>\operatorname{deg} \, g(x) \leqslant n/2</math>. Тогда <math>\forall a \in \mathbb{Z} \; g(a) \in \mathbb{Z}</math>, следовательно <math>f(a) \vdots g(a)</math>. Рассмотрим <math>m=n/2+1</math> различных целых чисел <math>a_i, i=\overline{1,m}</math> таких, что <math>f(a_i)\not=0</math>. Поскольку числа <math>f(a_i)</math> имеют конечное количество целых делителей, можно перебрать всевозможные наборы значений для <math>g(a_i)</math>. По каждому такому набору построим интерполяционный многочлен <math>g^*(x)</math> степени <math>m-1=n/2</math>. Если теперь <math>f(x)\mathrel{\vdots}g^*(x)</math>, к многочленам <math>g^*(x)</math> и <math>\frac{f(x)}{g^*(x)}</math> можно применить тот же метод, и так до тех пор, пока все множители не станут неприводимыми. В противном случае, если <math>\forall g^*(x) \ f(x)\mathrel{\cancel\vdots} g^*(x)</math>, многочлен <math>f(x)</math> уже является неприводимым.


== Алгоритм Кронекера (одномерный) ==
== Одномерный алгоритм Кронекера ==


=== Запись алгоритма ===
Дано: <math>f(x) \in \mathbb{Z}[x]</math> <br />
Надо: <math>g(x) \in \mathbb{Z}[x]</math><br />
'''Дано:''' <math>f(x) \in \mathbb{Z}[x]</math>
<math>n</math> - степень полинома <math>f</math>, <math>m</math> - степень полинома <br /><math>g</math>, <math>i</math> - целочисленное.<br />
Цикл от <math>i = 0</math> до <math>[n/2]</math><br />
если <math>f(i) = 0</math>, то <math>g=x-i</math>, <math>m=1</math>, успешно найден ответ.<br />
Конец если. Конец цикла. Если не успешно найден ответ то<br />
Цикл от <math>i = 0</math> до <math>[n/2]</math><br />
<math>U</math> - множество делителей <math>f(i)</math> (целочисленных)<br />
цикл для каждого <math>u \in U</math><br />
построить многочлен <math>g</math> степени <math>i</math>, такой, что<br />
<math>g(j)=u(j)</math> для <math>j=0...i</math><br />
если <math>f</math> делиться на <math>g</math>, то<br />
<math>m=i</math>, решение успешно найдено, ответ <math>g(j)</math><br />
Конец если, конец цикла, конец цикла, конец если.<br />
Конец.<br />


'''Надо:''' <math>g(x) \in \mathbb{Z}[x]</math>
ЗАМЕЧАНИЕ. Достаточно научиться разлагать на множители многочлены со старшим коэффициентом, равным единице.


'''Где:''' <math>n</math> — степень полинома <math>f</math>, <math>m</math> — степень полинома <math>g</math>, <math>i</math> — целочисленное.


<code>
== Пример ==
'''''Цикл''''' от <math>i = 0</math> до <math>[n/2]</math>
<math>f(x)=x^5-x^4-2x^3-8x^2+6x-1</math>(это многочлен с целыми коэффициентами и без рациональных корней). Если <math>f(x) = g(x)*h(x)</math> где степень k многочлена <math>g(x)</math> не больше степени <math>h(x)</math>, то k=2. Пусть Тогда f(0)=1; f(1)= -5; f(2)=-21. Делители этих чисел: для первого +1 и -1, для второго +1, -1, +5, -5, для третьего 1, 3, 7, 21. Всего получается <math>2*4*8=64</math> комбинации. Две комбинации отличающиеся лишь знаком, дают два многочлена. Поэтому можно проверять лишь половину. Остаются 32 случая. Перебирая все эти случаи, можно найти лишь один многочлен 2-й степени, делящий <math>f(x)</math>. Это <math>g(x)=x^2-3x+1</math>. Оба сомножителя этого разложения неприводимы (как многочлены 2-й и 3-й степеней, не имеющие рациональных корней).
:'''''Если''''' (<math>f(i) = 0</math>) то
::<math>g=x-i</math>
::<math>m=1</math>
::Ответ найден.
:'''''Конец если'''''
'''''Конец цикла'''''

'''''Если''''' (ответ не найден) то
: <math>U</math> — множество делителей <math>f(0)</math> (целочисленных)
:'''''Цикл''''' от <math>i = 1</math> до <math>[n/2]</math>
:: <math>M</math> — множество делителей <math>f(i)</math> (целочисленных)
:: <math>U := </math> декартово произведение <math>U</math> и <math>M</math>
:: '''''Цикл''''' для каждого <math>u \in U</math>
::: Построить многочлен <math>g</math> степени <math>i</math>, такой, что <math>g(j)=u(j)</math> для <math>j=0...i</math>
::: '''''Если''''' (<math>f</math> делится на <math>g</math>) то
:::: <math>m=i</math>
:::: Решение успешно найдено, ответ <math>g</math>
::: '''''Конец если'''''
:: '''''Конец цикла'''''
: '''''Конец цикла'''''
'''''Конец если'''''

'''''Конец.'''''
</code>

ЗАМЕЧАНИЕ. Достаточно научиться разлагать на множители многочлены со старшим коэффициентом, равным единице. Действительно, если старший коэффициент равен <math>a</math>, то домножив на <math>a^{n-1}</math> и сделав замену <math>x = y/a</math>, сводим задачу к этому случаю. После её решения остается сделать обратную замену и сократить на общий множитель a<sub>n−1</sub> . Однако этот метод обычно оказывается неэффективным: из-за увеличения коэффициентов ухудшаются различные оценки и скорость работы алгоритмов. Поэтому в большинстве работающих алгоритмов таких преобразований не производится.

=== Реализация на Maple ===
<source lang="pascal">
kronecker:=proc(f::polynom)
local g,i,n,U,V,j;
with(linalg);
n:=degree(f)/2;
U:=myfactor(subs(x=0,f));
for i from 1 to n do
U:=U,myfactor(subs(x=i,f));
V:=mcarp(U);
for j in V do
g:=interp([$0..i],j,x);
if rem(f,g,x)=0 and not type(g,'constant') then
print(g);
end if;
end do;
end dо;
end proc;

myfactor:=proc(n::integer)
local a,b,i,j;
b:=[];
for i from 1 to abs(n) do
if (irem(n,i)=0) then
b:=ArrayTools[Concatenate](2,b,i);
b:=ArrayTools[Concatenate](2,b,-i);
end if;
end do;
convert(b,'list');
end proc;

# Next 2 functions computes cartesian product of multiple sets.
# They are taken from http://people.oregonstate.edu/~peterseb/mth355/docs/355f2001-cartesian-product.pdf
carp:=proc(X,Y)
local Z,x,y;
Z:={};
for x in X do
for y in Y do
Z:=Z union {[x,y]};
end do;
end do;
return Z;
end proc;

mcarp:=proc()
local Z,k,x,y; option remember;
if nargs=0 then
Z:={};
elif nargs=1 then
Z:=args[1];
else Z:={};
for x in mcarp( seq(args[k], k=1..nargs-1) ) do
for y in args[nargs] do
Z:= Z union {[op(x),y]};
end do;
end do;
end if;
return Z;
end proc;

</source>

=== Пример ===
<math>f(x)=x^5-x^4-2x^3-8x^2+6x-1</math>(это многочлен с целыми коэффициентами и без рациональных корней). Если <math>f(x) = g(x) h(x)</math> где степень k многочлена <math>g(x)</math> не больше степени <math>h(x)</math>, то <math>k=2</math>. Тогда <math>f(0)=-1; f(1)=-5; f(2)=-21</math>. Делители этих чисел: для первого +1 и −1, для второго +1, −1, +5, −5, для третьего +1,-1, +3, -3, +7,-7,+ 21, -21. Всего получается <math>2 \cdot 4 \cdot 8=64</math> комбинации. Две комбинации отличающиеся лишь знаком, дают по сути один многочлен. Поэтому можно проверять лишь половину. Остаются 32 случая. Перебирая все эти случаи, можно найти лишь один многочлен 2-й степени, делящий <math>f(x)</math>. Это <math>g(x)=x^2-3x+1</math>. Оба сомножителя этого разложения неприводимы (как многочлены 2-й и 3-й степеней, не имеющие рациональных корней).

== Многомерный алгоритм Кронекера ==

=== Запись условий задачи ===
Пусть <math>D</math> — область целостности с однозначным разложением на множители, <math>f(x_1,...,x_n) \in D[x_1,...,x_n]</math>. Требуется разложить <math>f</math> на неприводимые множители.

=== Запись алгоритма ===
'''Дано''': <math>f \in \mathbb{Z} [x_1,...,x_n]</math>

'''Надо''': <math>G</math> — разложение

'''Переменные''': многочлен <math> \bar{f} \in \mathbb{Z}[y]</math>, разложение <math> \bar{G} </math> многочлена <math> \bar{f} </math>, множество <math>M</math> элементов типа <math>\mathbb{Z}</math>.

'''Идея реализации''': Редуцировать задачу к одномерному случаю, путём введения новой неизвестной и заменой всех переменных достаточно высокими степенями этой неизвестной. Факторизовать получившийся многочлен. Выполнить обратную подстановку, пробным делением убедиться, получено ли желаемое разложение.

'''Начало'''<br />
Выбрать целое <math>d</math> большее, чем степени отдельных переменных в <math>f</math> заменить все переменные степенями новой неизвестной <math>y</math>:
<center><math>\bar{f}(y):=S_d(f)=f(y,y^d,...,y^{d^{n-1}})</math></center>
Разложить <math>\bar{f}(y)</math> на неприводимые множители, то есть
<center><math> \bar{f}(y)= \bar{g}_1(y)... \bar{g}_s(y), \quad \bar{g}_i(y) \in \mathbb{Z}[y], \quad 1 \leq i \leq s</math></center>
<math>G</math>.число_множителей := 1

<math>m:=1</math>

<math>M:=\{1,...,s\}</math>

<code>
'''''Цикл пока''''' <math>m \leq [s/2]</math>
:'''''Цикл для каждого''''' подмножества <math>{i_1,...,i_m} \subset M</math> '''''пока''''' <math>m \leq [s/2]</math>
::<math>g_{i_1,...,i_m}(x_1,...,x_n):=S^{-1}_d(\bar{g}_{i_1}(y) \bar{g}_{i_2}(y)...\bar{g}_{i_m}(y))</math>
::'''''Если''''' <math>f</math> делится на <math>g</math> '''''то'''''
:::<math>G</math>.множитель[<math>G</math>.число_множителей]:=<math>g</math>
:::<math>G</math>.число_множителей:=<math>G</math>.число_множителей + 1
:::<math>f:=f/g</math>
:::<math>s:=s - m</math>
:::<math>M</math>.удалить{<math>i_1,...,i_m</math>}
::'''''Конец если'''''
:'''''Конец цикла'''''
:<math>m:=m+1</math>
'''''Конец цикла'''''<br />
<math>G</math>.множитель[<math>G</math>.число_множителей]:=<math>f</math><br/>
'''''Конец'''''
</code>

В этом алгоритме обратное преобразование <math>S^{-1}_d</math> определяется на одночленах по формуле:
<center><math>S^{-1}_d(y^{b_1+db_2+...+d^{v-1}b_v})=x_{1}^{b_1}...x_{v}^{b_v}</math></center>
<math>(0 \leq b_i < d</math> для <math>1 \leq i \leq v, \quad v \in \mathbb{Z})</math>, далее <math>S^{-1}_d</math> распространяется по линейности.


== Литература ==
== Литература ==
* Е. В. Панкратьев "Элементы компьютерной алгебры." М.:МГУ, 2007;
* Е. В. Панкратьев «Элементы компьютерной алгебры.» М.:МГУ, 2007;
* Kronecker L., "J. reine und angew. Math.", 1882;
* Kronecker L. «J. reine und angew. Math.», 1882;
* Окунев Л. Я., Высшая алгебра, М., 1937;
* Окунев Л. Я. «Высшая алгебра», М., 1937;
* Курош А. Г., Курс высшей алгебры, 11 изд., М., 1975;
* Курош А. Г. «Курс высшей алгебры», 11 изд., М., 1975;


{{math-stub}}
{{rq|refless|isbn}}


[[Категория:Многочлены]]
[[Категория:Многочлены]]
[[Категория:Численные методы]]

Текущая версия от 03:03, 10 июля 2019

Метод Кронекера — метод разложения многочлена с целыми коэффициентами на неприводимые множители над кольцом целых чисел; предложен в 1882 Кронекером.

Алгоритм Кронекера находит для данного многочлена многочлен , такой, что делится на , или доказывает, что такого многочлена нет.

Описание метода

[править | править код]

Алгоритм Кронекера основан на следующих соображениях:

  1. Если степень многочлена равна , то степень хотя бы одного множителя многочлена не превосходит  ;
  2. Значения как , так и в целых точках — целые числа, причем ) делит для любого целого ;
  3. При фиксированном , если не равно 0, то может принимать только конечное множество значений, состоящее из делителей числа ;
  4. Коэффициенты многочлена однозначно восстанавливаются по его значениям в точке.

Таким образом, для получается конечное число возможностей; непосредственным делением проверяем, получили ли делитель многочлена .

Строгое Изложение:

Рассмотрим  — многочлен степени . Пусть приводим над . Тогда и один из двух многочленов и имеет степень не выше . Пусть без ограничения общности . Тогда , следовательно . Рассмотрим различных целых чисел таких, что . Поскольку числа имеют конечное количество целых делителей, можно перебрать всевозможные наборы значений для . По каждому такому набору построим интерполяционный многочлен степени . Если теперь , к многочленам и можно применить тот же метод, и так до тех пор, пока все множители не станут неприводимыми. В противном случае, если , многочлен уже является неприводимым.

Одномерный алгоритм Кронекера

[править | править код]

Запись алгоритма

[править | править код]

Дано:

Надо:

Где:  — степень полинома ,  — степень полинома ,  — целочисленное.

Цикл от до

Если () то
Ответ найден.
Конец если

Конец цикла

Если (ответ не найден) то

— множество делителей (целочисленных)
Цикл от до
 — множество делителей (целочисленных)
декартово произведение и
Цикл для каждого
Построить многочлен степени , такой, что для
Если ( делится на ) то
Решение успешно найдено, ответ
Конец если
Конец цикла
Конец цикла

Конец если

Конец.

ЗАМЕЧАНИЕ. Достаточно научиться разлагать на множители многочлены со старшим коэффициентом, равным единице. Действительно, если старший коэффициент равен , то домножив на и сделав замену , сводим задачу к этому случаю. После её решения остается сделать обратную замену и сократить на общий множитель an−1 . Однако этот метод обычно оказывается неэффективным: из-за увеличения коэффициентов ухудшаются различные оценки и скорость работы алгоритмов. Поэтому в большинстве работающих алгоритмов таких преобразований не производится.

Реализация на Maple

[править | править код]
kronecker:=proc(f::polynom)
 local g,i,n,U,V,j;
 with(linalg);
 n:=degree(f)/2; 
 U:=myfactor(subs(x=0,f));
 for i from 1 to n do
   U:=U,myfactor(subs(x=i,f));
   V:=mcarp(U);
   for j in V do   
    g:=interp([$0..i],j,x);
    if rem(f,g,x)=0 and not type(g,'constant') then     
      print(g);               
    end if;
   end do;
  end dо;  
end proc;

myfactor:=proc(n::integer)
 local a,b,i,j;
 b:=[];
 for i from 1 to abs(n) do
  if (irem(n,i)=0) then  
   b:=ArrayTools[Concatenate](2,b,i);
   b:=ArrayTools[Concatenate](2,b,-i);
  end if;
 end do;
 convert(b,'list');
end proc;

# Next 2 functions computes cartesian product of multiple sets.
# They are taken from http://people.oregonstate.edu/~peterseb/mth355/docs/355f2001-cartesian-product.pdf
carp:=proc(X,Y)
 local Z,x,y;
 Z:={};
 for x in X do
  for y in Y do
   Z:=Z union {[x,y]};
  end do;
 end do;
 return Z;
end proc;

mcarp:=proc()
 local Z,k,x,y; option remember;
  if nargs=0 then
   Z:={};
  elif nargs=1 then
   Z:=args[1];
  else Z:={};
   for x in mcarp( seq(args[k], k=1..nargs-1) ) do
    for y in args[nargs] do
    Z:= Z union {[op(x),y]};
    end do;
   end do;
  end if;
 return Z;
end proc;

(это многочлен с целыми коэффициентами и без рациональных корней). Если где степень k многочлена не больше степени , то . Тогда . Делители этих чисел: для первого +1 и −1, для второго +1, −1, +5, −5, для третьего +1,-1, +3, -3, +7,-7,+ 21, -21. Всего получается комбинации. Две комбинации отличающиеся лишь знаком, дают по сути один многочлен. Поэтому можно проверять лишь половину. Остаются 32 случая. Перебирая все эти случаи, можно найти лишь один многочлен 2-й степени, делящий . Это . Оба сомножителя этого разложения неприводимы (как многочлены 2-й и 3-й степеней, не имеющие рациональных корней).

Многомерный алгоритм Кронекера

[править | править код]

Запись условий задачи

[править | править код]

Пусть — область целостности с однозначным разложением на множители, . Требуется разложить на неприводимые множители.

Запись алгоритма

[править | править код]

Дано:

Надо:  — разложение

Переменные: многочлен , разложение многочлена , множество элементов типа .

Идея реализации: Редуцировать задачу к одномерному случаю, путём введения новой неизвестной и заменой всех переменных достаточно высокими степенями этой неизвестной. Факторизовать получившийся многочлен. Выполнить обратную подстановку, пробным делением убедиться, получено ли желаемое разложение.

Начало
Выбрать целое большее, чем степени отдельных переменных в заменить все переменные степенями новой неизвестной :

Разложить на неприводимые множители, то есть

.число_множителей := 1

Цикл пока

Цикл для каждого подмножества пока
Если делится на то
.множитель[.число_множителей]:=
.число_множителей:=.число_множителей + 1
.удалить{}
Конец если
Конец цикла

Конец цикла
.множитель[.число_множителей]:=
Конец

В этом алгоритме обратное преобразование определяется на одночленах по формуле:

для , далее распространяется по линейности.

Литература

[править | править код]
  • Е. В. Панкратьев «Элементы компьютерной алгебры.» М.:МГУ, 2007;
  • Kronecker L. «J. reine und angew. Math.», 1882;
  • Окунев Л. Я. «Высшая алгебра», М., 1937;
  • Курош А. Г. «Курс высшей алгебры», 11 изд., М., 1975;