Zaawansowane algorytmy i struktury danych/Wykład 4: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Sank (dyskusja | edycje)
Sank (dyskusja | edycje)
Linia 42: Linia 42:
Niech <math>C</math> będzie wynikiem mnożenia
Niech <math>C</math> będzie wynikiem mnożenia
wielomianów <math>A</math> i <math>B</math>, mamy wtedy
wielomianów <math>A</math> i <math>B</math>, mamy wtedy


<center>
<center>
<math>C(x_i) = A(x_i)\cdot B(x_i)</math>.
<math>C(x_i) = A(x_i)\cdot B(x_i)</math>.
</center>
</center>


Ponieważ stopień wielomianu <math>C</math> jest nie większy niż
Ponieważ stopień wielomianu <math>C</math> jest nie większy niż
<math>2n</math> to z [[ZASD Moduł 4#interpolacja| Twierdzenia o interpolacji]] zbiór wartości
<math>2n</math> to z [[ZASD Moduł 4#interpolacja| Twierdzenia o interpolacji]] zbiór wartości


<center>
<center>
Linia 54: Linia 57:
\ldots, (2x_{n-1}, A(x_{2n-1})B(x_{2n-1})) \}</math>,
\ldots, (2x_{n-1}, A(x_{2n-1})B(x_{2n-1})) \}</math>,
</center>
</center>


jednoznacznie wyznacza wielomian <math>A \times B</math>. Mając
jednoznacznie wyznacza wielomian <math>A \times B</math>. Mając
Linia 59: Linia 63:
<math>X_C</math> w czasie <math>O(n)</math>. Procedura ta jest
<math>X_C</math> w czasie <math>O(n)</math>. Procedura ta jest
przedstawiona na następującym rysunku:
przedstawiona na następującym rysunku:


<center>
<center>
<flash>file=Zasd_fft1.swf|width=460|height=350</flash>
<flash>file=Zasd_fft1.swf|width=460|height=350</flash>
</center>
</center>


Jednak aby ostatecznie otrzymać szybszy algorytm niż algorytm naiwny
Jednak aby ostatecznie otrzymać szybszy algorytm niż algorytm naiwny

Wersja z 08:09, 19 lip 2006

Abstrakt

Naturalna metoda dodawania dwóch wielomianów wymaga czasu Θ(n), natomiast prosty algorytm mnożenia dwóch wielomianów stopnia n wymaga czasu Θ(n2). W wykładzie tym pokażemy, jak z wykorzystaniem szybkiej transformaty Fouriera (STF), wykonać wszystkie podstawowe operacje na wielomianach w czasie większym niż Θ(n) o czynnik polilogarytmiczny. Pokażemy jak dla wielomianów stopnia n:

  • mnożyć je w czasie O(nlogn),
  • obliczać wielomian interpolacyjny w czasie O(nlog2n),
  • obliczać wartość wielomianu w n punktach w czasie O(nlog2n),
  • dzielić wielomiany w czasie O(nlog3n).

Mnożenie wielomianów w punktach

Niech A(x)=i=0n1aixi i B(x)=i=0n1bixi będzą wielomianami stopnia n nad ciałem F. Wielomiany te możemy jednoznaczne reprezentować poprzez ich wartości w n punktach. Następujące twierdzenie zostało sformułowane w ramach wykładu z Metod Numerycznych.

Twierdzenie [Twierdzenie o interpolacji wielomianów]

Dla dowolnego zbioru n par X={(x0,y0),(x1,y1),,(xn1,yn1)} takiego, że wszystkie wartości xi są parami różne, istnieje jedyny wielomian C(x) stopnia n taki, że C(xi)=yi dla i=0,1,,n1.


Niech X będzie ustalonym zbiorem parami różnych punktów x0,,x2n1F. Dla tego zbioru punktów możemy wyznaczyć zbiory wartości wielomianów:


XA={(x0,A(x0)),(x1,A(x1),,(x2n1,A(x2n1))}

XB={(x0,B(x0)),(x1,B(x1),,(x2n1,B(x2n1))}


Niech C będzie wynikiem mnożenia wielomianów A i B, mamy wtedy


C(xi)=A(xi)B(xi).


Ponieważ stopień wielomianu C jest nie większy niż 2n to z Twierdzenia o interpolacji zbiór wartości


XA×B={(x0,A(x0)B(x0)),(x1,A(x1)B(x1),,(2xn1,A(x2n1)B(x2n1))},


jednoznacznie wyznacza wielomian A×B. Mając zbiory XA i XB możemy wyznaczyć zbiór XC w czasie O(n). Procedura ta jest przedstawiona na następującym rysunku:


<flash>file=Zasd_fft1.swf|width=460|height=350</flash>


Jednak aby ostatecznie otrzymać szybszy algorytm niż algorytm naiwny musimy pokazać jak rozwiązać problem obliczania wartości wielomianu w n punktach w czasie szybszym niż Θ(n2). Podobnie musimy umieć obliczać wielomian interpolacyjny dla danego zbioru punktów.

Szybka transformata Fouriera (STF)

Problem obliczania wartości wielomianu w n punktach i problem jego interpolacji rozwiążemy wykorzystując szybką transformatę Fouriera. W poprzednim rozdziale nie zakładaliśmy nic na temat zbioru punktów X. Głównym pomysłem w konstrukcji algorytmu STF będzie właśnie wybór odpowiedniego zbioru punktów X tak, aby jak największa ilość wykonywanych obliczeń powtarzała się.

Założymy chcemy obliczyć wartości wielomianu A(x)=i=0n1aixi oraz n jest parzyste. Jeżeli n jest nieparzyste to dodajemy na początek A(x) jednomian 0xn+1 co nie zmienia nam wyniku działania algorytmu. Punkty Xn={x0,x1,,xn1} zdefiniujemy w następujący sposób:

xi=e2πin.

Dla wielomianu A(x) definiujemy dwa nowe wielomiany A[0](x) i A[1](x) poprzez wybranie do nich współczynników A(x) o numerach odpowiednio parzystych i nieparzystych:

A[0](x)=a0+a2x+a4x2++an2xn21,

A[1](x)=a1+a3x+a5x2++an1xn21.

Wielomiany A[0](x) oraz A[1](x) są stopnia co najwyżej n2. Co więcej zachodzi:

A(x)=A[0](x2)+xA[1](x2) (1).

Widzimy teraz, że problem ewaluacji wielomianu A(x) w punktach ωn0,ωn1,,ωnn1 sprowadza się do:

  • ewaluacji wielomianów A[0](x) i A[1](x)

w punktach

X={x02,x12,,xn12}.

  • a następnie obliczenie wartości A(x)wyniku zgodnie ze wzorem (1).

Zauważmy, że z definicji punktów $x_i$ mamy:

xi2=(e2πin)2=e2πin/2.

Możemy teraz zauważyć, że zachodzi xi2=xi+n22, a więc X=Xn2. Udało nam się więc zredukować problem rozmiaru n --- obliczenia wartości wielomianu A(x) stopnia n w ndo punktach, do dwóch problemów rozmiaru n2 --- obliczenia wartości wielomianów A[0](x) i A[1](x) stopnia n2 w n2 punktach. Możemy teraz zastosować tą technikę rekurencyjne otrzymując następujący algorytm.

Równanie rekurencyjne na czas działania procedury STF wygląda następująco:

T(n)=2T(n2)+Θ(n)=Θ(nlogn).

Odwrotna transformata Fouriera

Aby zakończyć konstrukcję algorytmu dla szybkiego mnożenia wielomianów pozostaje nam pokazanie jak wykonać obliczyć wielomian interpolujący dla zbioru punktów Xn. Obliczenie wykonane w czasie szybkiej transformaty Fouriera możemy przedstawić w postaci macierzowej jako mnożenie macierzy przez wektor (A(x0),A(x1),,A(xn1))T=Vn(a0,a1,,an1)T, gdzie V(x0,,xn1) jest macierzą Vandermonde'a zawierającą potęgi xi

(A(x0)A(x1)A(x2)A(xn1))=[x00x01x02x03x0n1x10x11x12x13x1n1x20x21x22x23x2n1xn10xn11xn12xn13xn1n1](a0a1a2an1)

Element macierzy V(x0,,xn1) dany jest jako

V(x0,,xn1)i,j=xij.

W celu wykonania operacji odwrotnej do SFT, czyli obliczenia wielomianu interpolacyjnego, musimy wykonać mnożenie V(x0,,xn1)1(A(x0),A(x1),,A(xn1))T.

Korzystając z definicji zbioru Xn otrzymujemy

V(x0,,xn1)i,j=(e2πin)j=e2πijn.

Lemat

cos tam costam

Dowód

aaaa