Asymptotisk analyse af algoritmers køretider
Analyse af køretid (RAM-modellen vs. virkeligheden) public class Linear { public static void main(string[] args) { long time = System.currentTimeMillis(); long n = Long.parseLong(args[0]); long total = 0; for(long i=1; i<=n; i++){ total = total + 1; System.out.println(total); System.out.println(System.currentTimeMillis() - time);
Analyse af køretid (RAM-modellen vs. virkeligheden) public class Linear { public static void main(string[] args) { long time = System.currentTimeMillis(); long n = Long.parseLong(args[0]); long total = 0; for(long i=1; i<=n; i++){ total = total + 1; System.out.println(total); System.out.println(System.currentTimeMillis() - time); T (n) = c 1 n + c 0
Analyse af køretid (RAM-modellen vs. virkeligheden) public class Linear { public static void main(string[] args) { long time = System.currentTimeMillis(); long n = Long.parseLong(args[0]); long total = 0; for(long i=1; i<=n; i++){ total = total + 1; System.out.println(total); System.out.println(System.currentTimeMillis() - time); T (n) = c 1 n + c 0 2.9e 06 Linear.java, plot af (målt tid)/n Linear.java ms (gennemsnit af 5 kørsler) 2.88e 06 2.86e 06 2.84e 06 x-akse: inputstørrelse n y-akse: (målt tid)/n 2.82e 06 2.8e 06 0 5e+08 1e+09 1.5e+09 2e+09 2.5e+09 3e+09 3.5e+09 4e+09 4.5e+09 n
Analyse af tidsforbrug (RAM-modellen vs. virkeligheden) for(long i=1; i<=n; i++){ for(long j=1; j<=n; j++){ total = total + 1;
Analyse af tidsforbrug (RAM-modellen vs. virkeligheden) for(long i=1; i<=n; i++){ for(long j=1; j<=n; j++){ total = total + 1; T (n) = (c 2 n + c 1 ) n + c 0 = c 2 n 2 + c 1 n + c 0
Analyse af tidsforbrug (RAM-modellen vs. virkeligheden) for(long i=1; i<=n; i++){ for(long j=1; j<=n; j++){ total = total + 1; T (n) = (c 2 n + c 1 ) n + c 0 = c 2 n 2 + c 1 n + c 0 Quadratic.java, plot af (målt tid)/n^2 4.4e 06 Quadratic.java 4.2e 06 ms/n^2 (gennemsnit af 5 kørsler) 4e 06 3.8e 06 3.6e 06 3.4e 06 3.2e 06 3e 06 x-akse: inputstørrelse n y-akse: (målt tid)/n 2 2.8e 06 2.6e 06 0 10000 20000 30000 40000 50000 60000 70000 n
Analyse af tidsforbrug (RAM-modellen vs. virkeligheden) for(long i=1; i<=n; i++){ for(long j=1; j<=n; j++){ for(long k=1; k<=n; k++){ total = total + 1;
Analyse af tidsforbrug (RAM-modellen vs. virkeligheden) for(long i=1; i<=n; i++){ for(long j=1; j<=n; j++){ for(long k=1; k<=n; k++){ total = total + 1; T (n) = ((c 3 n+c 2 ) n+c 1 ) n+c 0 = c 3 n 3 +c 2 n 2 +c 1 n+c 0
Analyse af tidsforbrug (RAM-modellen vs. virkeligheden) for(long i=1; i<=n; i++){ for(long j=1; j<=n; j++){ for(long k=1; k<=n; k++){ total = total + 1; T (n) = ((c 3 n+c 2 ) n+c 1 ) n+c 0 = c 3 n 3 +c 2 n 2 +c 1 n+c 0 1e 05 Cubic.java, plot af (målt tid)/n^3 Cubic.java 9e 06 ms/n^3 (gennemsnit af 5 kørsler) 8e 06 7e 06 6e 06 5e 06 4e 06 x-akse: inputstørrelse n y-akse: (målt tid)/n 3 3e 06 2e 06 0 200 400 600 800 1000 1200 1400 1600 1800 2000 n
Linear vs. kvadratisk vs. kubisk ms (gennemsnit af 5 kørsler) 100000 10000 1000 100 10 plot af målt tid (dobbelt-logaritmisk) Linear.java Quadratic.java Cubic.java 1 100 1000 10000 100000 1e+06 1e+07 1e+08 1e+09 1e+10 n
Multiplikative konstanter Multiplikative konstanter ligegyldige hvis voksehastighed er forskellig: f (n) = 3000n h(n) = 3n 2 g(n) = 4000n k(n) = 4n 2 1.2e+07 1e+07 3000*x 4000*x 3*x**2 4*x**2 8e+06 6e+06 4e+06 2e+06 0 0 200 400 600 800 1000 1200 1400 1600
Multiplikative konstanter Multiplikative konstanter ligegyldige hvis voksehastighed er forskellig: f (n) = 3000n h(n) = 3n 2 g(n) = 4000n k(n) = 4n 2 1.2e+07 1e+07 3000*x 4000*x 3*x**2 4*x**2 8e+06 6e+06 4e+06 2e+06 0 0 200 400 600 800 1000 1200 1400 1600 3000n < 4n 2 3000/4 < n 750 < n
Multiplikative konstanter Multiplikative konstanter ligegyldige hvis voksehastighed er forskellig: f (n) = 3000n h(n) = 3n 2 g(n) = 4000n k(n) = 4n 2 1.2e+07 1e+07 3000*x 4000*x 3*x**2 4*x**2 8e+06 6e+06 4e+06 2e+06 0 0 200 400 600 800 1000 1200 1400 1600 3000n < 4n 2 3000/4 < n 750 < n A n < B n 2 A/B < n
Asymptotisk notation Vi ønsker at sammenligne funktioners essentielle voksehastighed på en måde så der ses bort fra multiplikative konstanter. Vi ønsker for voksehastighed for funktioner sammenligninger svarende til de fem klassiske ordens-relationer: = < > De vil, af historiske årsager, blive kaldt for: O Ω Θ o ω Hvilket udtales således: Store O, Omega, Theta, lille o, lille omega Følgende definitioner har vist sig at fungere godt:
Store O Mening: f g i voksehastighed
Store Omega Mening: f g i voksehastighed
Theta Mening: f = g i voksehastighed
Lille o Mening: f < g i voksehastighed
Lille omega Mening: f > g i voksehastighed
Asymptotisk notation Man kan nemt vise at disse definitioner opfører sig som forventet af ordens-relationer. F.eks.: f (n) = o(g(n)) f (n) = O(g(n)) (jvf. x < y x y)
Asymptotisk notation Man kan nemt vise at disse definitioner opfører sig som forventet af ordens-relationer. F.eks.: f (n) = o(g(n)) f (n) = O(g(n)) (jvf. x < y x y) f (n) = Θ(g(n)) f (n) = O(g(n)) (jvf. x = y x y )
Asymptotisk notation Man kan nemt vise at disse definitioner opfører sig som forventet af ordens-relationer. F.eks.: f (n) = o(g(n)) f (n) = O(g(n)) (jvf. x < y x y) f (n) = Θ(g(n)) f (n) = O(g(n)) (jvf. x = y x y ) f (n) = O(g(n)) g(n) = Ω(f (n)) (jvf. x y y x )
Asymptotisk notation Man kan nemt vise at disse definitioner opfører sig som forventet af ordens-relationer. F.eks.: f (n) = o(g(n)) f (n) = O(g(n)) (jvf. x < y x y) f (n) = Θ(g(n)) f (n) = O(g(n)) (jvf. x = y x y ) f (n) = O(g(n)) g(n) = Ω(f (n)) (jvf. x y y x ) f (n) = o(g(n)) g(n) = ω(f (n)) (jvf. x < y y > x )
Asymptotisk notation Man kan nemt vise at disse definitioner opfører sig som forventet af ordens-relationer. F.eks.: f (n) = o(g(n)) f (n) = O(g(n)) (jvf. x < y x y) f (n) = Θ(g(n)) f (n) = O(g(n)) (jvf. x = y x y ) f (n) = O(g(n)) g(n) = Ω(f (n)) (jvf. x y y x ) f (n) = o(g(n)) g(n) = ω(f (n)) (jvf. x < y y > x ) f (n) = O(g(n)) og f (n) = Ω(g(n)) g(n) = Θ(g(n)) (jvf. x y og x y x = y )
Asymptotisk analyse De asymptotiske forhold mellem de fleste funktioner f og g kan afklares ved følgende sætninger: Hvis f (n) k > 0 for n så gælder f (n) = Θ(g(n)) g(n) Hvis f (n) 0 for n så gælder f (n) = o(g(n)) g(n)
Asymptotisk analyse De asymptotiske forhold mellem de fleste funktioner f og g kan afklares ved følgende sætninger: Hvis f (n) k > 0 for n så gælder f (n) = Θ(g(n)) g(n) Eksempler: Hvis f (n) 0 for n så gælder f (n) = o(g(n)) g(n) 20n 2 + 17n + 312 20 + 17/n + 312/n2 n 2 = 20 + 0 + 0 = 20 for n 1 1
Asymptotisk analyse De asymptotiske forhold mellem de fleste funktioner f og g kan afklares ved følgende sætninger: Hvis f (n) k > 0 for n så gælder f (n) = Θ(g(n)) g(n) Eksempler: Hvis f (n) 0 for n så gælder f (n) = o(g(n)) g(n) 20n 2 + 17n + 312 20 + 17/n + 312/n2 n 2 = 20 + 0 + 0 = 20 for n 1 1 20n 2 + 17n + 312 n 3 = 20/n + 17/n2 + 312/n 3 = 0 + 0 + 0 = 0 for n 1 1
Asymptotisk analyse Derudover er det godt at vide følgende fact fra matematik: For alle a > 0 og b > 1 gælder n a b n 0 for n
Asymptotisk analyse Derudover er det godt at vide følgende fact fra matematik: For alle a > 0 og b > 1 gælder n a b n 0 for n Dvs. ethvert polynomium er o() af enhver exponentialfunktion
Asymptotisk analyse Derudover er det godt at vide følgende fact fra matematik: For alle a > 0 og b > 1 gælder n a b n 0 for n Dvs. ethvert polynomium er o() af enhver exponentialfunktion Eksempelvis giver dette at: hvoraf ses n 100 2 n 0 for n n 100 = o(2 n )
Asymptotisk analyse Regel fra sidste slide: For alle a > 0 og b > 1 gælder na b n 0 for n
Asymptotisk analyse Regel fra sidste slide: For alle a > 0 og b > 1 gælder na b n 0 for n For c > 1 og d > 0, sæt N = log c (n) og b = c d. Så haves (log c n) a n d = N a (c log c (n) ) d = Na c d log c (n) = N a Na = (c d ) log c (n) (c d ) N
Asymptotisk analyse Regel fra sidste slide: For alle a > 0 og b > 1 gælder na b n 0 for n For c > 1 og d > 0, sæt N = log c (n) og b = c d. Så haves (log c n) a n d = N a (c log c (n) ) d = Na c d log c (n) = og derfor fås følgende variant af reglen: N a Na = (c d ) log c (n) (c d ) N For alle a, d > 0 og c > 1 gælder (log c n) a 0 for n n d
Asymptotisk analyse Regel fra sidste slide: For alle a > 0 og b > 1 gælder na b n 0 for n For c > 1 og d > 0, sæt N = log c (n) og b = c d. Så haves (log c n) a n d = N a (c log c (n) ) d = Na c d log c (n) = N a Na = (c d ) log c (n) (c d ) N og derfor fås følgende variant af reglen: For alle a, d > 0 og c > 1 gælder (log c n) a n d 0 for n Dvs. enhver logaritme (selv opløftet i enhver potens) er o() af ethvert polynomium.
Asymptotisk analyse Regel fra sidste slide: For alle a > 0 og b > 1 gælder na b n 0 for n For c > 1 og d > 0, sæt N = log c (n) og b = c d. Så haves (log c n) a n d = N a (c log c (n) ) d = Na c d log c (n) = N a Na = (c d ) log c (n) (c d ) N og derfor fås følgende variant af reglen: For alle a, d > 0 og c > 1 gælder (log c n) a n d 0 for n Dvs. enhver logaritme (selv opløftet i enhver potens) er o() af ethvert polynomium. Eksempelvis giver dette at: (log n) 3 n 0.5 0 for n, hvoraf ses (log n) 3 = o(n 0.5 )
Større eksempel Disse regler forklarer at følgende funktioner er sat i stigende voksehastighed (den ene er o() af den næste): 1, log n, n, n/ log n, n, n log n, n n, n 2, n 3, n 10, 2 n
Dominerende led Bemærk at dominerende led (led med højeste voksehastighed) bestemmer samlet voksehastighed. Eksempel (figur): f (n) = 700n 2 g(n) = 7n 3 h(n) = 600n 2 + 500n + 400 k(n) = 6n 3 + 5n 2 + 4n + 3 3.5e+07 3e+07 700*x**2 600*x**2 + 500*x + 400 7*x**3 6*x**3 + 5*x**2 + 4*x + 3 2.5e+07 2e+07 1.5e+07 1e+07 5e+06 0 0 20 40 60 80 100 120 140 160
Dominerende led Bemærk at dominerende led (led med højeste voksehastighed) bestemmer samlet voksehastighed. Eksempel (figur): f (n) = 700n 2 g(n) = 7n 3 h(n) = 600n 2 + 500n + 400 k(n) = 6n 3 + 5n 2 + 4n + 3 3.5e+07 3e+07 700*x**2 600*x**2 + 500*x + 400 7*x**3 6*x**3 + 5*x**2 + 4*x + 3 2.5e+07 2e+07 1.5e+07 1e+07 5e+06 0 0 20 40 60 80 100 120 140 160 Figuren passer med beregninger:
Dominerende led 6n 3 + 5n 2 + 4n + 3 6 + 5/n + 4/n2 7n 3 = 6 + 0 + 0 = 6/7 for n 7 7 Dvs. 6n 3 + 5n 2 + 4n + 3 = Θ(7n 3 )
Dominerende led 6n 3 + 5n 2 + 4n + 3 6 + 5/n + 4/n2 7n 3 = 6 + 0 + 0 = 6/7 for n 7 7 Dvs. 6n 3 + 5n 2 + 4n + 3 = Θ(7n 3 ) 600n 2 + 500n + 400 600 + 500/n + 400/n2 700n 2 = 600 + 0 + 0 = 6/7 for n 700 700 Dvs. 600n 2 + 500n + 400 = Θ(700n 2 )
Dominerende led 6n 3 + 5n 2 + 4n + 3 6 + 5/n + 4/n2 7n 3 = 6 + 0 + 0 = 6/7 for n 7 7 Dvs. 6n 3 + 5n 2 + 4n + 3 = Θ(7n 3 ) 600n 2 + 500n + 400 600 + 500/n + 400/n2 700n 2 = 600 + 0 + 0 = 6/7 for n 700 700 Dvs. 600n 2 + 500n + 400 = Θ(700n 2 ) 600n 2 + 500n + 400 6n 3 + 5n 2 + 4n + 3 = 600/n + 500/n1 + 400/n 2 6 + 5/n 1 + 4/n 2 + 3/n 3 0 + 0 + 0 6 + 0 + 0 + 0 = 0 for n Dvs. 600n 2 + 500n + 400 = o(6n 3 + 5n 2 + 4n + 3)