Föreläsning 3: Dekomposition Dekomposition Dekomposition är en generell metod för att lösa problem Metoden bygger på att man delar upp ett problem i delproblem av samma typ som ursprungsproblemet Uppdelningen fortsätter sedan tills problemet är nerbrutet i många triviala delproblem Resultaten från delproblemen sätts sedan ihop till en lösning av ursprungsproblemet Komplexitetens beroende av problemets storlek kan oftast beräknas genom analys av ett rekursionssamband Sortering Två algoritmer för sortering i tid O(n log n): Mergesort, Ouicksort Båda bygger på dekomposition MergeSort MergeSort(v[ij]) (1) if i<j (2) m i+j 2 (3) MergeSort(v[im]) (4) MergeSort(v[m +1j]) (5) v[ij] =Merge(v[im],v[m +1j]) Låt T (N) vara tiden för att sortera N tal Då gäller { O(1) N =1 T (N) = T ( ) ( N 2 + T N ) 2 +Θ(N) annars eftersom Merge tar tid Θ(N) när indata är vektorer av längd N Denna typ av rekursionssamband är vanlig vid analys av algoritmer Master Theorem Sats För a 1, b>1 och d>0 har rekursionsekvationen lösningen T (1) = d T (n) =at (n/b)+f(n) T (n) =Θ(n log b a ) om f(n) =O(n log b a ɛ ) för något ɛ>0 T (n) =Θ(n log b a log n) om f(n) =Θ(n log b a ) T (n) =O(f(n)) om f(n) =Ω(n log b a+ɛ ) för något ɛ>0 och af(n/b) cf(n) för något c<1 för alla tillräckligt stora n Tillämpad på analysen av MergeSort fås att tidskomplexiteten är Θ(N log N)
Mer om dekomposition Vi vill bestämma x y där x och y binärt ges av x = x x n/2 x x 1 x 0 =2 n/2 a + b }{{}}{{} a b y = y y n/2 y y 1 y 0 =2 n/2 c + d }{{}}{{} c d För n =2 k kan vi använda dekomposition: Mult(x, y) (1) if length(x) =1 (2) return x y (3) else (4) [a, b] x (5) [c, d] y (6) prod 2 n Mult(a, c)+mult(b, d) +2 n/2 (Mult(a, d)+mult(b, c)) (7) return prod Tidskomplexitet: T (n) =4T (n/2) + Θ(n), T (1) = Θ(1) så T (n) =Θ(n 2 )
Karatsubas multiplikationsalgoritm Utnyttja (a + b)(c + d) =ac + bd +(ad + bc) En av de fyra multiplikationerna kan tas bort: Mult(x, y) (1) if length(x) =1 (2) return x y (3) else (4) [a, b] x (5) [c, d] y (6) ac Mult(a, c) (7) bd Mult(b, d) (8) abcd Mult(a + b, c + d) (9) return 2 n ac + bd+ 2 n/2 (abcd ac bd) Nu fås T (n) =3T (n/2)+θ(n), T (1) = Θ(1) med lösningen T (n) =Θ(n log 2 3 ) O(n 159 ) Ännu bättre prestanda kan fås om man delar talen i tre eller fler delar r delar ger O(n log r (2r 1) ) I praktiken är det inte säkert att detta lönar sig om inte n är väldigt stort Dekomposition leder till en del overhead som kan ta en stor del av tiden för små instanser Matrismultiplikation Vid multiplikation av n n-matriser kan man använda blockmatrisform: ( )( ) ( ) A11 A 12 B11 B 12 C11 C = 12 A 21 A 22 B 21 B 22 C 21 C 22 Genom sambanden C 11 = A 11 B 11 + A 12 B 21 C 12 = A 11 B 12 + A 12 B 22 C 21 = A 21 B 11 + A 22 B 21 C 22 = A 21 B 12 + A 22 B 22 får man 8 multiplikationer och således { Θ(1) n =1 T (n) = 8T (n/2) + Θ(n 2 ) n>1 och därmed T (n) =Θ(n 3 )
Strassens algoritm Genom sambanden M 1 =(A 12 A 22 )(B 21 + B 22 ) M 2 =(A 11 + A 22 )(B 11 + B 22 ) M 3 =(A 11 A 21 )(B 11 + B 12 ) M 4 =(A 11 + A 12 )B 22 M 5 = A 11 (B 12 B 22 ) M 6 = A 22 (B 21 B 11 ) M 7 =(A 21 + A 22 )B 11 C 11 = M 1 + M 2 M 4 + M 6 C 12 = M 4 + M 5 C 21 = M 6 + M 7 C 22 = M 2 M 3 + M 5 M 7 kan antalet multiplikationer minskas från 8 till 7 så T (n) =Θ(n log 2 7 )=O(n 281 ) Snabb Fouriertransform (FFT) Givet två polynom A(x) = a jx j och B(x) = b jx j, hur bestämmer man effektivt produkten C(x) = 2() c j x j? Hur fort det går beror på vilken representation som används Två vanliga representationer: Koefficientform Ett polynom representeras som de n koefficienterna Punkt-värde-form Polynomet A(x) representeras som n par (x i,y i ) där y i = A(x i )Den talen x i är fixa Koefficientform: Att evaluera ett polynom A(x) = a jx j på koefficientform kräver n multiplikationer med Horners regel: A(x) =a 0 + x(a 1 + x(a 2 + x(a 3 ))) Att addera A(x) = a jx j och B(x) = b jx j tar O(n) tid medan det tar Θ(n 2 ) tid att multiplicera dem Går det att multiplicera polynom snabbare? Punkt-värde-form: Att multiplicera två polynom på punkt-värde-form går snabbt (O(n) multiplikationer) om de är evaluerade i samma 2n punkter: Produkten av {(x i,y i )} och {(x i,z i )} är {(x i,y i z i )} och summan är {(x i,y i + z i )} Å andra sidan är det knepigare att evaluera ett polynom på punkt-värde-form i en godtycklig punkt Att gå från punkt-värde-form till koefficientform (dvs interpolera) kan göras på Θ(n 2 ) tid med Lagranges interpolationsformel: k j A(x) = y (x x k) j k j (x j x k )
Schematisk multiplikationsalgoritm: Koefficientform lämpar sig bra för evaluering i godtyckliga punkter medan punktvärde-form lämpar sig bra för multiplikation Kombinera styrkorna hos de båda representationerna! Multiplikation av A(x) och B(x): 1 Evaluera polynomen i punkterna x i 2 Multiplicera polynomen på punkt-värde-form 3 Interpolera tillbaka till koefficientform Problem: Hur ska punkterna x i väljas så att evalueringen och interpolationen går snabbt? Diskreta fouriertransformen Evaluera polynomen i de komplexa enhetsrötterna ω 0 n,ω 1 n,,ω n där ω n = e 2πi/n Transformen av A(x) = a jx j skrivs där DFT n ( a 0,,a )= y 0,,y y k = A(ωn)= k a j e 2πijk/n De n koefficienterna ger n frekvenser Jämför ˆf(t) = som är den kontinuerliga transformen f(x)e itx dx FFT: Effektiv beräkning av DFT Vi har y k = A(ωn k )= a j e 2πijk/n Separera udda och jämna gradtal i A: För k<n/2 är A(x) = a 2j (x 2 ) j + x = A [0] (x 2 )+xa [1] (x 2 ) A [0] (ωn 2k )= a 2j e 4πijk/n = a 2j ω jk n/2 a 2j+1 (x 2 ) j = DFT n/2 ( a 0,a 2,,a n 2 ) k där DFT n ( a 0,,a ) k är det k:te elementet av transformen
På samma sätt fås, för k<n/2, För k n/2 kan man lätt visa att A [1] (ω 2k n )=DFT n/2( a 1,a 3,,a ) k A [0] (ω 2k n )=DFT n/2 ( a 0,a 2,,a n 2 ) k n/2 A [1] (ω 2k n )=DFT n/2 ( a 1,a 3,,a ) k n/2 ω k n = ω k n/2 n För att bestämma DFT n ( a 0,,a ) utgår vi alltså från DFT n/2 ( a 0,a 2,,a n 2 ) och DFT n/2 ( a 1,a 3,,a ) och kombinerar ihop lämpliga värden FFTär ett exempel på dekomposition basfallet är DFT 1 ( a 0 )= a 0 Vi antar att n är en tvåpotens Algoritm för FFT DFT n ( a 0,a 1,a ) (1) if n =1 (2) return a 0 (3) ω n e 2πi/n (4) ω 1 (5) y [0] DFT n/2 ( a 0,a 2,,a n 2 ) (6) y [1] DFT n/2 ( a 1,a 3,,a ) (7) for k =0to n/2 1 (8) y k y [0] k (9) y k+n/2 y [0] + ωy[1] k k ωy[1] k (10) ω ω ω n (11) return y 0,y 1,,y Tidskomplexiteten T (n) uppfyller { O(1) n =1 T (n) = 2T (n/2) + Θ(n) n > 1 med lösningen T (n) =Θ(n log n) Invers till DFT För att gå tillbaka från punkt-värde-form till koefficientform måste DFT inverteras Relationen y = DFT n (a) kan på matrisform skrivas 0 B @ y 0 y 1 y 1 0 ωn 0 ωn 0 ωn 0 ω C A = n 0 ωn 1 ωn B @ ωn 0 ωn ω n ()() 1 0 C B A @ a 0 a 1 a 1 C A
Inversen a = DFTn 1 (y) svarar mot att matrisen ovan inverteras Man kan visa att DFT 1 n ( y 0,y 1,,y )= a 0,a 1,,a a j = 1 y k ωn jk n k=0 så FFT-algoritmen kan användas också för bestämning av DFT 1 Polynommultiplikation med FFT Vi vill bestämma C(x) = 2n 2 c ix i = A(x)B(x) där A(x) och B(x) har grad EftersomC(x) har 2 koefficienter duger det inte att arbeta med DFT n vi måste betrakta A(x) och B(x) som polynom av grad 2n 1 Algoritm: y 0,y 2 DFT 2n ( a 0,,a, 0,,0 ) z 0,z 2 DFT 2n ( b 0,,b, 0,,0 ) c 0,c 2 DFT2n 1 ( y 0z 0,,y 2 z 2 ) (Detta förutsätter att n är en tvåpotens) Tre DFT på vektorer av längd 2n och 2n multiplikationer i transformplanet Θ(n log n) tid Tillämpningar av FFT Inom bla följande områden använder man DFTeller besläktade transformer Signalteori DFTger den diskreta motsvarigheten till frekvensspektrum Bildbehandling DFToch DCT(diskreta cosinustransformen) används för analys och komprimering Aritmetik på stora tal De effektivaste algoritmerna för multiplikation (tid O(n log n log log n)) använder FFT