More actions
Bez shrnutí editace |
Bez shrnutí editace Značka: editor wikitextu 2017 |
||
Riadok 5: | Riadok 5: | ||
Algoritmy, s ktorými sme sa streli v [[Asymptotická notácia|predošlej téme]] mali rôzne hranice ich výpočtových zložitostí. Ale čo to vlastne znamená že tieto funkcie majú určitú hranicu? | Algoritmy, s ktorými sme sa streli v [[Asymptotická notácia|predošlej téme]] mali rôzne hranice ich výpočtových zložitostí. Ale čo to vlastne znamená že tieto funkcie majú určitú hranicu? | ||
Vysvetlime to na jednoduchom kóde:<syntaxhighlight lang="python3"> | Vysvetlime to na jednoduchom kóde: | ||
<syntaxhighlight lang="python3"> | |||
# existuje n.index(...), ale to by sme si toho moc neukázali: | # existuje n.index(...), ale to by sme si toho moc neukázali: | ||
def najdi_index_prvku(zoznam, hladaj): | def najdi_index_prvku(zoznam, hladaj): | ||
Riadok 13: | Riadok 15: | ||
return -1 # prvok sa nenašiel | return -1 # prvok sa nenašiel | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Keďže zoznam na vstupe je usporiadanou množinou, môže nastať viacero situácií. Napríklad:<syntaxhighlight lang="python3"> | Časová zložitosť tohto algoritmu je <math>O(n)</math> (lineárna), priestorová <math>O(1)</math> (konštantná – nepoužíva dodatočnú pamäť). | ||
Keďže zoznam na vstupe je usporiadanou množinou, môže nastať viacero situácií. Napríklad: | |||
<syntaxhighlight lang="python3"> | |||
zoznam = [1, 2, 3] | zoznam = [1, 2, 3] | ||
Riadok 32: | Riadok 38: | ||
# (teda, vždy by sme mali ideálne podmienky a najlepší prípad), tak by zložitosť bola | # (teda, vždy by sme mali ideálne podmienky a najlepší prípad), tak by zložitosť bola | ||
# konštantná = O(1), pretože by sme vykonali iba jednu operáciu porovnania | # konštantná = O(1), pretože by sme vykonali iba jednu operáciu porovnania | ||
</syntaxhighlight>Vidíme dva prípady: | </syntaxhighlight> | ||
Vidíme dva prípady: | |||
* V prvom je časová zložitosť <math>O(n)</math>, pretože '''musíme prejsť všetkými prvkami v zozname''' – a nakoniec zistíme, že sa tam prvok aj tak '''nenachádza'''. | * V prvom je časová zložitosť <math>O(n)</math>, pretože '''musíme prejsť všetkými prvkami v zozname''' – a nakoniec zistíme, že sa tam prvok aj tak '''nenachádza'''. | ||
Riadok 42: | Riadok 50: | ||
* ''Poznámka:'' v oboch prípadoch je priestorová zložitosť <math>O(1)</math>, pretože samotný algoritmus nepotrebuje žiadnu dodatočnú pamäť ktorá by sa menila v závislosti od <math>n</math>. | * ''Poznámka:'' v oboch prípadoch je priestorová zložitosť <math>O(1)</math>, pretože samotný algoritmus nepotrebuje žiadnu dodatočnú pamäť ktorá by sa menila v závislosti od <math>n</math>. | ||
Z toho vyplýva, že v závislosti od usporiadania prvkov na vstupe a hodnoty ktorú hľadáme sa môže zmeniť aj výpočtová zložitosť algoritmu. Avšak, v praxi sme pesimisti a najčastejšie vždy vyjadrujeme Big-O notáciu (teda, <math>O(f(n))</math>), pretože predpokladáme Murphyho zákon, teda:<blockquote>Všetko čo sa môže pokaziť, sa pokazí.</blockquote>Asi si vieš predstaviť, že to tak naozaj funguje. Ale niekedy je možno užitočné vyjadriť aj '''priemerný prípad''' – je to v podstate spojenie hornej a dolnej hranice funkcie výpočtovej zložitosti, a vyjadrujeme ju ako Theta: <math>\Theta(f(n))</math>. Theta notáciu môžeme použiť iba vtedy, ak vieme že '''priemerná zložitosť je presne ohraničená zhora aj zdola rovnakou funkciou'''. | Z toho vyplýva, že v závislosti od usporiadania prvkov na vstupe a hodnoty ktorú hľadáme sa môže zmeniť aj výpočtová zložitosť algoritmu. Avšak, v praxi sme pesimisti a najčastejšie vždy vyjadrujeme Big-O notáciu (teda, <math>O(f(n))</math>), pretože predpokladáme Murphyho zákon, teda: | ||
<blockquote>Všetko čo sa môže pokaziť, sa pokazí.</blockquote> | |||
Asi si vieš predstaviť, že to tak naozaj funguje. Ale niekedy je možno užitočné vyjadriť aj '''priemerný prípad''' – je to v podstate spojenie hornej a dolnej hranice funkcie výpočtovej zložitosti, a vyjadrujeme ju ako Theta: <math>\Theta(f(n))</math>. Theta notáciu môžeme použiť iba vtedy, ak vieme že '''priemerná zložitosť je presne ohraničená zhora aj zdola rovnakou funkciou'''. | |||
V skratke: | V skratke: | ||
Riadok 50: | Riadok 62: | ||
* Ak je rast výpočtovej zložitosti algoritmu presne '''obmedzený rovnakou funkciou zhora aj zdola''', použijeme '''Theta''' notáciu; | * Ak je rast výpočtovej zložitosti algoritmu presne '''obmedzený rovnakou funkciou zhora aj zdola''', použijeme '''Theta''' notáciu; | ||
Existuje aj algoritmus, ktorý dokáže obsiahnuť všetky príklady:<syntaxhighlight lang="python3"> | Existuje aj algoritmus, ktorý dokáže obsiahnuť všetky príklady: | ||
<syntaxhighlight lang="python3"> | |||
def spocitaj_prvky(mnozina): | def spocitaj_prvky(mnozina): | ||
pocet = 0 | pocet = 0 | ||
Riadok 58: | Riadok 72: | ||
return pocet | return pocet | ||
</syntaxhighlight>V tomto algoritme je najhorší prípad zároveň aj najlepším. Bez ohľadu na veľkosť alebo usporiadanie prvkov v poli musíme vždy prejsť všetkými prvkami. Preto sú všetky notácie časovej zložitosti lineárne: | </syntaxhighlight> | ||
V tomto algoritme je najhorší prípad zároveň aj najlepším. Bez ohľadu na veľkosť alebo usporiadanie prvkov v poli musíme vždy prejsť všetkými prvkami. Preto sú všetky notácie časovej zložitosti lineárne: | |||
* pre hornú (Big-O) hranicu: <math>O(n)</math>; | * pre hornú (Big-O) hranicu: <math>O(n)</math>; | ||
* pre dolnú (Omega) hranicu: <math>\Omega(n)</math>; | * pre dolnú (Omega) hranicu: <math>\Omega(n)</math>; | ||
* pre priemernú (Theta) hranicu: spojenie hornej a dolnej hranice, v podstate stále iba <math>\Theta(n)</math>; | * pre priemernú (Theta) hranicu: spojenie hornej a dolnej hranice, v podstate stále iba <math>\Theta(n)</math>; | ||
{{Téma | {{Téma | ||
| Oblast = Kategória:Algoritmy a výpočtová zložitosť | | Oblast = Kategória:Algoritmy a výpočtová zložitosť | ||
| Poradie = 30 | | Poradie = 30 | ||
}} | }} | ||
[[Kategória:Algoritmy a výpočtová zložitosť]] | [[Kategória:Algoritmy a výpočtová zložitosť]] |
Verzia z 17:39, 13. február 2025
Asymptotická horná a dolná hranica funkcie zložitosti, najlepší, priemerný a najhorší prípad, asymptotická presná notácia.
Algoritmy, s ktorými sme sa streli v predošlej téme mali rôzne hranice ich výpočtových zložitostí. Ale čo to vlastne znamená že tieto funkcie majú určitú hranicu?
Vysvetlime to na jednoduchom kóde:
# existuje n.index(...), ale to by sme si toho moc neukázali:
def najdi_index_prvku(zoznam, hladaj):
for n, prvok in enumerate(zoznam): # n = index aktuálneho prvku
if prvok == hladaj:
return n
return -1 # prvok sa nenašiel
Časová zložitosť tohto algoritmu je (lineárna), priestorová (konštantná – nepoužíva dodatočnú pamäť).
Keďže zoznam na vstupe je usporiadanou množinou, môže nastať viacero situácií. Napríklad:
zoznam = [1, 2, 3]
hladaj = 4
index = najdi_index_prvku(zoznam, hladaj)
print(index) # vypíše -1
# prvok neexistuje, musíme teda prejsť celým zoznamom
# časová zložitosť je preto O(n)
# (ak predpokladáme, že prvok sa nikdy nebude v zozname nachádzať = najhorší prípad)
hladaj = 1
index = najdi_index_prvku(zoznam, hladaj)
print(index) # vypíše 0
# číslo 1 sa nachádza na prvom indexe (0), čo predstavuje najlepší (ideálny) prípad
# ak by sa hľadaný prvok vždy nachádzal na prvom mieste
# (teda, vždy by sme mali ideálne podmienky a najlepší prípad), tak by zložitosť bola
# konštantná = O(1), pretože by sme vykonali iba jednu operáciu porovnania
Vidíme dva prípady:
- V prvom je časová zložitosť , pretože musíme prejsť všetkými prvkami v zozname – a nakoniec zistíme, že sa tam prvok aj tak nenachádza.
- Toto sa nazýva: najhorší prípad;
- Vyjadruje ju notácia Big-O: ;
- V druhom prípade je časová zložitosť , pretože hľadaný prvok sa nachádza na prvom mieste, vykonáme teda iba jednu operáciu porovnania (a zložitosť je konštantná).
- Toto sa nazýva: najlepší prípad;
- Vyjadruje ju notácia Omega: ;
- Poznámka: v oboch prípadoch je priestorová zložitosť , pretože samotný algoritmus nepotrebuje žiadnu dodatočnú pamäť ktorá by sa menila v závislosti od .
Z toho vyplýva, že v závislosti od usporiadania prvkov na vstupe a hodnoty ktorú hľadáme sa môže zmeniť aj výpočtová zložitosť algoritmu. Avšak, v praxi sme pesimisti a najčastejšie vždy vyjadrujeme Big-O notáciu (teda, ), pretože predpokladáme Murphyho zákon, teda:
Všetko čo sa môže pokaziť, sa pokazí.
Asi si vieš predstaviť, že to tak naozaj funguje. Ale niekedy je možno užitočné vyjadriť aj priemerný prípad – je to v podstate spojenie hornej a dolnej hranice funkcie výpočtovej zložitosti, a vyjadrujeme ju ako Theta: . Theta notáciu môžeme použiť iba vtedy, ak vieme že priemerná zložitosť je presne ohraničená zhora aj zdola rovnakou funkciou.
V skratke:
- Ak vieme len hornú hranicu, ale nie dolnú, použijeme Big-O notáciu;
- Ak vieme len dolnú hranicu, ale nie hornú, použijeme Omega notáciu;
- Ak je rast výpočtovej zložitosti algoritmu presne obmedzený rovnakou funkciou zhora aj zdola, použijeme Theta notáciu;
Existuje aj algoritmus, ktorý dokáže obsiahnuť všetky príklady:
def spocitaj_prvky(mnozina):
pocet = 0
for _ in mnozina:
pocet += 1
return pocet
V tomto algoritme je najhorší prípad zároveň aj najlepším. Bez ohľadu na veľkosť alebo usporiadanie prvkov v poli musíme vždy prejsť všetkými prvkami. Preto sú všetky notácie časovej zložitosti lineárne:
- pre hornú (Big-O) hranicu: ;
- pre dolnú (Omega) hranicu: ;
- pre priemernú (Theta) hranicu: spojenie hornej a dolnej hranice, v podstate stále iba ;