Big O notácia: analýza zložitosti algoritmov

Vývojári sa už od začiatku nástupu informačných technológií snažia písať kód, ktorý nielen funguje, ale aj efektívne využíva hardvér. Kedysi, keď procesory boli drahé a pomalé a pamäte málo, sa výrazne optimalizovalo a záležalo doslova na každej strojovej inštrukcii. Podobne to bolo pri práci s veľkými množinami údajov a algoritmy museli byť veľmi sofistikované, pretože výpočtový čas bol do veľkej miery limitovaný.

Preto vznikla potreba porovnávať efektivitu algoritmov a práve toto je miesto, kde notácia Big O zohráva významnú úlohu. V tomto článku sa pozrieme bližšie na analýzu algoritmickej zložitosti pomocou notácie Big O.

Big O notácia – čo to vlastne je?

BIG O notácia je matematický zápis v počítačovej vede, ktorá sa používa na opis asymptotickej zložitosti algoritmov, to znamená opisuje najhorší možný scenár (hornú hranicu) algoritmu na základe veľkosti vstupných dát. Inými slovami, táto notácia nám pomáha pochopiť, ako sa mení efektívnosť algoritmu v závislosti od množstva údajov, ktoré sa využívajú.

graf Big O notácia
graf Big O notácia

Krátka história BIG O zápisu

Jej teoretické základy boli položené začiatkom dvadsiateho storočia, keď ľudia o počítačových algoritmoch ani nesnívali, avšak v počítačovej vede sa Big O notácia stala populárnou a široko používanou až v 60. rokoch 20. storočia, hlavne vďaka priekopníkom ako Donald Knuth. Knuth podrobne rozpracoval a popularizoval používanie tejto notácie vo svojom známom diele The Art of Computer Programming, prvýkrát publikovanom v roku 1968. Knuthovo dielo významne prispelo k štandardizácii a rozšíreniu používania Big O notácie v analýze algoritmov a počítačových programov.

Použitie a vlastnosti BIG O notácie

Zápis BIG O sa používa na teoretické porovnanie efektivity rôznych algoritmov. Napr. ak sa rozhodujeme, ktorý triediaci algoritmus je vhodnejšie v danej situácii použiť, pozrieme si zápis pre rôzne algoritmy.

Rovnako nám pomáha predpovedať, ako sa bude algoritmus správať s množstvom narastajúcich vstupných údajov. Táto znalosť je nevyhnutným predpokladom pre optimalizovanie algoritmu a efektívnejšie využívanie zdrojov.

Pri riešení zložitých problémov môže znalosť zložitosti veľkého O rôznych algoritmov viesť k výberu vhodných dátových štruktúr a algoritmov. To nám pomáha navrhnúť efektívne riešenia problémov v reálnom svete.

Táto notácia sa používa pri analýze časovej a priestorovej zložitosti algoritmov. Časovú zložitosť sme už spomínali, priestorová zložitosť je vyjadrená pomocou notácie Big O na opis hornej hranice využitia pamäte algoritmom.

Pochopenie zápisu BIG O

V zápise Big O predstavuje O poradie funkcie a f(n) predstavuje funkciu popisujúcu časovú zložitosť algoritmu z hľadiska vstupnej veľkosti n. Zápis O(f(n)) znamená, že časová zložitosť algoritmu nerastie rýchlejšie ako špecifická funkcia so vstupom n. Matematická funkcia f(n) teda popisuje, ako sa zvyšuje doba behu algoritmu s rastúcou veľkosťou vstupu. Napr. zápis O(n) hovorí, že čas vykonávania algoritmu rastie lineárne s veľkosťou vstupu.

BIG O notácia – príklady

Teraz si ukážeme najpoužívanejšie typy zložitosti, ako sa zapisujú pomocou BIG o notácie a príklad algoritmu s danou zložitosťou v prehľadnej tabuľke.

BIG O zápis Zložitosť Príklad algoritmu
O(1) konštantná Prístup k prvku v poli pomocou indexu
O(log n) logaritmická Binárne vyhľadávanie v zotriedenom poli
O(n) lineárna Lineárne vyhľadávanie cez nezoradené pole
O(n log n) linearitmická Efektívne triediace algoritmy ako napr. mergesort
O(n²) kvadratická 2 vnorené slučky iterujúce cez vstup
O(2n) exponenciálna Brute force algoritmy testujúce všetky kombinácie
O(n!) faktorová Algoritmus generujúce všetky permutácie množiny

Pravidlá používania notácie Big O

Pri používaní Big O notácie existuje niekoľko základných pravidiel, ktoré pomáhajú presne a konzistentne vyjadriť asymptotickú zložitosť algoritmov. Big O notácia sa dá používať rovnako pre časovú aj priestorovú zložitosť.

Ignorovanie nižších rádov

Pri určovaní Big O notácie sa berie do úvahy iba najvyšší rád. Nižšie rády a konštanty sú zanedbateľné, pretože ich vplyv sa stáva zanedbateľným pri veľkých vstupoch.

Príklad: Ak má algoritmus časovú zložitosť f(n) = 3n² + 5n + 82, zložitosť je O(n²) , pretože n² je najvyšší rád.

Ignorovanie konštánt

Konštantné faktory sú zanedbateľné, pretože nemajú významný vplyv na rast funkcie pri veľkých vstupoch.

Príklad: Ak má algoritmus časovú zložitosť  f(n) = 2n, zložitosť je O(n) .

Súčet

Ak je algoritmus zložený z niekoľkých krokov, ktoré sa vykonávajú sekvenčne, celková zložitosť je určená najvyšším rádom medzi jednotlivými krokmi.

Príklad: Ak má algoritmus dve časti so zložitosťou O(n) a O(n²), celková zložitosť je O(n²).

Súčin

Ak algoritmus obsahuje vnorené cykly, celková zložitosť je súčinom zložitostí jednotlivých cyklov.

Príklad: Ak má vonkajší cyklus zložitosť O(n)) a vnútorný cyklus tiež zložitosť O(n), celková zložitosť je O(n * n) = O(n²).

Logaritmy

Logaritmické funkcie rastú pomalšie ako polynomiálne funkcie, takže sú často v praxi zanedbateľné oproti polynomiálnym.

Náš tip  – praktické využitie pri programovaní

Ak sme naimplementovali nejaký algoritmus a chceme zistiť jeho zložitosť bez toho, aby sme si začali analyzovať časové zložitosti jednotlivých blokov kódu, môžeme daný algoritmus postupne spúšťať pre vstupné dáta 1 až N a odmerať si čas behu rutiny. Z týchto nameraných hodnôt si potom vieme v Exceli zostrojiť graf závislosti vstupných dát (osa x) od času priebehu algoritmu (osa y). Podľa tvaru krivky potom vieme približne identifikovať zložitosť algoritmu a v závislosti od typu algoritmu potom zistíme, či existuje priestor na jeho optimalizáciu.

O autorovi

Jozef Wagner

Java Developer Senior

Viac ako 10 rokov programujem v Jave, momentálne pracujem v msg life Slovakia ako Java programátor senior a pomáham zákazníkom implementovať ich požiadavky do poistného softvéru Life Factory. Vo voľnom čase si rád oddýchnem v lese, prípadne si zahrám nejakú dobrú počítačovú hru.

Daj nám o sebe vedieť