You are on page 1of 17

Algoritmin analysointi kertaluokkaperiaatteella

• Tarkastellaan suoritusajan tms. resurssin kertaluokkaa.

– Jätetään huomiotta vakiokertoimet ja (suhteellisen) pienet termit.

• Algoritmien suhteellisia tehokkuuksia voidaan vertailla suurella syöttötiedon koolla.

– Asymptoottisesti tehokkaamman algoritmin valitseminen.

• Esim. suoritusaika on muotoa T (n) = an2 + bn + c, jossa a > 0, b, c vakioita

– suurilla n termit bn ja c eivät merkittäviä

– suurilla n vakiokerroin a ei merkittävä

– jos n kasvaa kaksinkertaiseksi, suoritusaika kasvaa noin nelinkertaiseksi

– suoritusajan kertaluokka on n2.


Funktioiden kasvunopeus
• Usein ollaan kiinnostuneita algoritmin käyttäytymisestä suurilla syötteillä.
• Algoritmin suoritusaikaa (tai muistinkäyttöä) kuvaavat funktiot voidaan laittaa asymp-
toottiseen suuruusjärjestykseen funktioiden suhteen raja-arvoa tarkastelemalla

f (n)  0
 , f (n) asymptoottisesti pienempi kuin g(n)
lim = vakio > 0 , f (n) asymptoottisesti yhtä suuri kuin g(n)
n→∞ g(n)  ∞

, f (n) asymptoottisesti suurempi kuin g(n).

Esim. f (n) = 100n2 + 30n + 45

a) g(n) = n3 : limn→∞ fg(n)


(n)
= 100
n + 30 + 45 = 0
n2 n3

b) g(n) = n2 : limn→∞ fg(n)


(n)
= 100 + 30
n + 45 = 100
n2

c) g(n) = n : limn→∞ fg(n)


(n)
= 100n + 30 + 45
n =∞

• L’Hôpitalin säännöstä voi olla apua asymptoottista suuruusjärjestystä laskettaessa,


jos raja-arvoksi näyttää tulevan 0 0 tai ∞ .

Esimerkki: Asymptoottinen suuruusjärjestys 3
exp(x)

en
x*exp(x)

limn→∞ = limn→∞ n 1 = 0,
nen 2.5

en on asymptoottisesti pienempi kuin nen 2

1.5

limn→∞ nlog
log2 n
= limn→∞ n = ∞,
2n 1

log2 n on asymptoottisesti pienempi kuin n log2 n


0.5

1
log2 n+n n ln
0
n log2 n 2
0 1 2 3 4 5

limn→∞ en = limn→∞ en
3
x*log(x)
log(x)

= limn→∞ loge
2 n + 1 lim
n ln 2 n→∞
1
en
2.5

1 2

= limn→∞ n ln 2 +0
en
1.5

= ln12 limn→∞ ne1n = 0,


n log2 n on asymptoottisesti pienempi kuin en
1

0.5

Funktiot (nousevassa) asympt. suuruusjärjestyk- 0


0 1 2 3 4 5

sessä: log2 n, n log2 n, en ja nen.


Asymptoottinen yläraja (O-notaatio)
• Merkintä f (n) = O(g(n)) (tai f (n) ∈ O(g(n)))
tarkoittaa, että f (n) on asymptoottisesti pienempi tai
yhtä suuri kuin g(n) (vrt. f ≤ g).
• f (n) = O(g(n)) ⇐⇒ 0 ≤ f (n) ≤ cg(n) joillakin
positiivisilla vakioilla c ja n0 , kaikille n ≥ n0 .
• Voidaan myös sanoa, että f on kertaluokkaa O(g(n)).
Esim. f (n) = 100n2 + 30n + 45 ≤ cn2 jollakin c, kun
n ≥ n0 (esim. c = 101 ja n0 = 39); 100n2 +30n+45
on kertaluokkaa O(n2 ).
• Syötteestä ja toteutuksesta riippumaton yläraja.
• Käytetään usein kuvaamaan pahinta tapausta; esim. väliinsijoitusmenetelmän pahimmassa tapauk-
sessa suoritusaika on O(n2 ) (rajoittaa ylhäältä päin suoritusaikaa kaikilla syötteillä).
• Voi käyttää edellä esitettyä määritelmää tai aiemmin esitettyä raja-arvotarkastelua

f (n)  0 , f (n) = O(g(n)), mutta g(n) ̸= O(f (n))
lim = vakio > 0 , f (n) = O(g(n)) ja g(n) = O(f (n))
n→∞ g(n)  ∞ , f (n) ̸= O(g(n)), mutta g(n) = O(f (n)).

Esim. kun f (n) = 100n2 + 30n + 45, f (n) ̸= O(n), f (n) = O(n2 ) ja f (n) = O(n3 ).
• Jos f (n) = O(nk ) jollakin vakiolla k, niin f (n) on polynomisesti rajoitettu.
• Ylipolynomisilla (eksponentiaalisilla) algoritmeilla ei suurta hyötyä laskenta-ajan pidentämisestä tai
laitteiston tehostamisesta.
Funktioiden kertaluokkia
Vakiofunktion suoritusaika ei riipu n:stä, joten kertaluokka on O(1).

Polynomeja
458 = O(n0) = O(1)
10n + 8 = O(n)
3n2 + 2n + 1 = O(n2) (pitää paikkansa myös: 3n2 + 2n + 1 = O(n3) jne.∗)
12n3 + 4n2 = O(n3)
ak nk + ak−1nk−1 + · · · + a1n + a0 = O(nk )

Logaritmifunktio
loga n = log b n ∀a, b > 1,
logb a
1 ̸= 0
logb a ⇒ loga n = O(logb n) ∀a, b > 1

∗ Käytännössä pyritään selvittämään kertaluokka mahdollisimman tarkasti tai ”tiukasti”. O(n2 ) on pienin kertaluokka,
joka sisältää funktion f (n) = 3n2 + 2n + 1, määritelmän mukaan kuitenkin myös f (n) = O(n3 ), f (n) =
O(n4 ), jne.
Kertaluokkamerkintöjen laskusääntöjä
Vaativuusfunktioiden vakiokertoimet jätetään huomioimatta.

k
aini = O(nk )
X

i=1
f (n) = O(f (n))
f (n) = O(n · f (n))
c · f (n) = O(f (n))
c + f (n) = O(f (n))
f (n) + g(n) = O(max{f (n), g(n)}) = max{O(f (n)), O(g(n))}
f (n) · g(n) = O(f (n) · g(n))
log10 n = O(log2 n)
Jos f (n) = O(g(n)) ja g(n) = O(h(n)), f (n) = O(h(n)).
Algoritmin analysointisääntöjä

• Sijoituslause vie vakioajan O(1).

• Peräkkäisten lauseiden kertaluokka saadaan “summasääntöä” käyttämällä.

• if-lauseen aika on ehtolausekkeen vaatima suoritusaika + ehdollisesti suoritetun


lauseen maksimisuoritusaika.

• Silmukan suoritusaika on silmukkalauseen lausekkeiden vaatima suoritusaika + sil-


mukan rungon suoritusaika summattuna yli kaikkien silmukan suorituskertojen.

• Aliohjelmakutsujen suoritusaikaa varten on ensin selvitettävä aliohjelman vaatima


suoritusaika.
Esimerkki: Väliinsijoitusmenetelmän pahimmassa tapauksessa suoritusaika O(n2)
// Väliinsijoitusmenetelmä Analysoidaan vaihteeksi silmukat sisältä ulospäin:
1 for (j = 1; j < n; j++) {
2 key = a[j]; Rivit 6-7: vain alkeisoperaatioita, T6−7 ≤ t1.
3 // Lisätään a[j] alkuosaan
4 i = j-1; Rivit 5-8: while-lauseen lisäksi enintään i + 1 = j
5 while (i >= 0 and a[i] > key) {
6 a[i+1] = a[i];
kertaa sisempi silmukka,
7 i = i-1; T5−8 ≤ t2 + (i + 1)t1 = t2 + jt1.
8 }
9 a[i+1] = key; Rivit 2-4: vain alkeisoperaatioita (ja kommentti,
10 }
jota ei suoriteta), T2−4 ≤ t3.
Alkeisoperaatiot vievät aikaa seuraavasti:
riveillä 6-7: t1
Rivit 2-9: T2−9 ≤ t3 + t2 + jt1
rivillä 5:t2
riveillä 2 ja 4 yhteensä: t3 Rivit 1-10: for-lauseen lisäksi rivit 2-9 suoritetaan,
rivillä 1: t4 kun j = 1, . . . , n − 1,
n−1
X n(n − 1)
T1−10(n) ≤ t4 + (t3 + t2 + jt1) = t4 + (t3 + t2)(n − 1) + t1
j=1 2
= (t1/2)n2 + (t2 + t3 − t1/2)n + (−t2 + t3 + t4) = O(n2)
Esimerkki
Oletetaan, että silmukoiden sisällä tehdään vain alkeisoperaatioita.
1. for (i=1; i<=n; i++){ 2. for (i=1; i<=n; i++){

for (j=1; j<=m; j++){ for (j=1; j<i; j++){

// sisemmän for-silmukan runko // sisemmän for-silmukan runko

} }
} }
Sisemmän for-silmukan runko suoritetaan Sisemmän for-silmukan runko suoritetaan
mn kertaa. Aikavaativuus on O(mn). n−1
X
j = 1 + 2 + · · · + (n − 1)
j=1
n(n − 1)
= kertaa.
2
Aikavaativuus on O(n2)
Esimerkki
1: s=0;
2: for(i=0;i<3*n;i++)
3: s=s+1
rivi 1 suoritetaan kerran
rivi 2 suoritetaan 3n + 1 kertaa
rivi 3 suoritetaan 3n kertaa (kun i = 0, 1, . . . , 3n − 1)
Suoritusaika yht. T (n) = t1 + t2 (3n + 1) + t3 · 3n = 3(t2 + t3 )n + (t1 + t2 ) ≤ cn jollakin c > 0

⇒ Ohjelmapätkän aikavaativuus on O(n)

Toinen tapa:

rivin 3 suoritusaika on vakio eli kertaluokkaa O(1) ja suorituskertoja 3n kpl


⇒ 3n · O(1) = O(3n) · O(1) = O(3n · 1) = O(3n) = O(n)
rivin 2 suoritusaika on vakio eli kertaluokkaa O(1) ja suorituskertoja (3n + 1) kpl
⇒ (3n + 1) · O(1) = O(3n + 1) · O(1) = O((3n + 1) · 1) = O(3n + 1) = O(n)
⇒ rivien 2-3 aikavaativuus O(n) + O(n) = max{O(n), O(n)} = O(max{n, n}) = O(n)
rivin 1 suoritusaika on vakio eli kertaluokkaa O(1) ja se suoritetaan kerran O(1)
⇒ rivien 1-3 aikavaativuus O(n) + O(1) = max{O(n), O(1)} = O(max{n, 1}) = O(n)

⇒Ohjelmapätkän aikavaativuus on O(n)


1: if ( k < n)
2: for (i = 0; i <= n; i++)
3: s = s + i;
4: else
5: for (i = 0; i < 5000; i++)
6: s = s + i;

Rivi 1 suoritetaan kerran.


Rivi 2 suoritetaan enintään n + 2 kertaa.
Rivi 3 suoritetaan enintään n + 1 kertaa.
Rivi 4 suoritetaan enintään kerran.
Rivi 5 suoritetaan joko 0 tai 5001 kertaa eli vakiomäärän kertoja.
Rivi 6 suoritetaan joko 0 tai 5000 kertaa eli vakiomäärän kertoja.
Ohjelman pätkän pahimman tapauksen vaativuus on O(n).

Tällaisessa tehtävässä voi siis olettaa, että n on suuri verrattuna mihin tahansa vakioon.
Määritelmät eri kertaluokkamerkinnöille
Tällä kurssilla keskitytään O-merkintään, mutta on myös muita kertaluokkamerkintöjä.

• Asymptoottinen yläraja O(g(n)) =


{f (n) : on pos. kok.luvut c, n0 s.e. 0 ≤ f (n) ≤ cg(n) kaikilla n ≥ n0}

• Asymptoottinen alaraja Ω(g(n)) =


{f (n) : on pos. kok.luvut c, n0 s.e. 0 ≤ cg(n) ≤ f (n) kaikilla n ≥ n0 }

• Asymptoottinen tarkka raja Θ(g(n)) =


{f (n) : on pos. kok.luvut c1 , c2 , n0 s.e. 0 ≤ c1 g(n) ≤ f (n) ≤ c2 g(n) kaikilla n ≥ n0 }

• Asymptoottinen aito yläraja o(g(n)) =


{f (n) : on pos. kok.luvut c, n0 s.e. 0 ≤ f (n) < cg(n) kaikilla n ≥ n0 , c > 0}

• Asymptoottinen aito alaraja ω(g(n)) =


{f (n) : on pos. kok.luvut c, n0 s.e. 0 ≤ cg(n) < f (n) kaikilla n ≥ n0 , c > 0}
Kertaluokkien määrittäminen raja-arvon avulla

• Asymptoottinen yläraja f (n) = O(g(n)), kun limn→∞ fg(n)


(n)
<∞

• Asymptoottinen alaraja f (n) = Ω(g(n)), kun limn→∞ fg(n)


(n)
>0

• Asymptoottinen tarkka raja f (n) = Θ(g(n)), kun 0 < limn→∞ fg(n)


(n)
<∞

• Asymptoottinen aito yläraja f (n) = o(g(n)), kun limn→∞ fg(n)


(n)
=0

• Asymptoottinen aito alaraja f (n) = ω(g(n)), kun limn→∞ fg(n)


(n)
=∞
Peruskertaluokkia
log2 n n n log2 n n2 n3 2n
0 1 0 1 1 2
1 2 2 4 8 4
2 4 8 16 64 16
3 8 24 64 512 256
4 16 64 256 4096 65536
5 32 160 1024 32768 4294967296

O(1) Vaatii vakioajan eli on riippumaton syötteen koosta.

O(log2 n) Logaritminen kertaluokka on usein tuloksena, kun ongelma jaetaan pie-


nempään osaongelmaan (pienentäen ongelman kokoa murto-osaan alkuperäisestä).
Logaritmin kantaluku vaikuttaa vain termin vakiokertoimeen, joten kantaluvulla ei
suuruusluokkaan vaikutusta.

O(n) Lineaarinen vaativuus on optimaalinen tapauksissa, joissa kaikki syöttötieto


käsiteltävä. Jokin operaatio tehdään kaikille alkioille.
O(n log2 n) Tämä on yleensä tuloksena, kun ongelma jaetaan osiin, ratkaistaan
kukin erikseen ja lopuksi vielä kootaan osaratkaisuista lopullinen tulos.

O(n2) Neliöllinen vaativuus on käyttökelpoinen yleensä suhteellisen pienen syöt-


tötiedon koon omaaville ongelmille. Tällöin yleensä algoritmi käsittelee ongelman
kaikki alkioparit.

O(n3) Kuutiollinen vaativuus sopii vain melko pienen syöttötiedon koon omaaville
ongelmille.

O(nk ) Polynominen vaativuus, k on vakio.

O(2n) Vain muutamia eksponentiaalinen vaativuuden omaavia algoritmeja voi-


daan käyttää käytännön ongelmiin.
• Jos f (n) = O(nk ) jollakin vakiolla k, niin f (n) on polynomisesti rajoitettu ja
ongelma on polynomisessa ajassa ratkeava (P).

• Ylipolynomisilla (eksponentiaalisilla) algoritmeilla ei suurta hyötyä laskenta-ajan pi-


dentämisestä tai laitteiston tehostamisesta.

• Osa ylipolynomisista ongelmista on NP-täydellisiä: ongelmalle ei tunneta polynomi-


aalisessa ajassa toimivaa algoritmia

– Esim. Hamiltonin kehäongelma


Tehtävänä on löytää reitti, joka käy tasan kerran jokaisessa verkon solmussa ja palaa lähtö-
solmuun.

• Jos jollekin NP-täydelliselle ongelmalle löytyy polynominen algoritmi, kaikki joukon


ongelmat voidaan ratkaista polynomisessa ajassa.
Päätösongelmien vaativuusluokkia

• P = { päätösongelmat, jotka voidaan ratkaista polynomisella algoritmilla }

• NP = { päätösongelmat, joiden ratkaisujen oikeellisuus voidaan tarkastaa polyno-


misessa ajassa }

• Selvästi P ⊆ NP

• Onko P = NP ?

You might also like