Asymptotické složitosti

Pořádně formálně zpracované - takto řekl cvičící, že má vypadat vzorové řešení. Mé správné, ale jen pomocí slov téměř poslal do koše.

Ač to mistři v recodexu zapisovali =O(n2)= O(n^2), tak se myslí O(n2)\in O(n^2), "Relace "=" znamená náležení do třídy funkcí."

Vycházíme z definice:

f(n)O(g(n))    cR+ n0N nn0:f(n)cg(n)f(n) \in O(g(n)) \iff \exists c \in \reals^+ \ \exists n_0 \in \natnums \ \forall n \ge n_0: f(n) \le c \cdot g(n)

f,g jsou funkce NR+f, g \text{ jsou funkce } \natnums \rightarrow \reals^+

Cituji z Průvodce (2022, sekce 2.4 Asymptotická notace, str. 50):

Nechť f,g:NRf, g: \natnums \rightarrow \reals jsou 2 funkce. Řekněme, že funkce f(n)f(n) je třídy O(g(n))O(g(n)), jestliže existuje taková realná kladná konstanta cc, že pro skoro všechna nn platí f(n)cg(n)f(n) \le c \cdot g(n). Skoro všemi nn se myslí, že nerovnost může selhat pro konečně mnoho výjímek, tedy, že existuje nějaké přirozené n0n_0 takové, že nerovnost platí pro všechna nn0n \ge n_0. Funkci g(n)g(n) se pak říká asymptotický horní odhad funkce f(n).

Na zápis O(g)O(g) bychom se mohli dívat jako na množinu všech funkcí ff, které splňují uvedenou definici. Proto můžeme místo "funkce ff je třídy O(g)O(g)" psát fO(g)f \in O(g). Navíc to umožní elegatně zapisovat různé vztahy typu O(n)O(n2)O(n) \subseteq O(n^2)

Průvodce to definuje to pro R\reals, ale tady v cvičení máme všechny funkce do R+\reals^+, a budeme toho v důkazech využívat, bude nám stačit definice pro R+\reals^+. Tu část s konstantně mnoho výjimkami budu používat.

f(n)Ω(g(n))    cR+ n0N nn0:f(n)cg(n)f(n) \in \Omega(g(n)) \iff \exists c \in \reals^+ \ \exists n_0 \in \natnums \ \forall n \ge n_0: f(n) \ge c \cdot g(n)

f,g jsou funkce NR+f, g \text{ jsou funkce } \natnums \rightarrow \reals^+

Dokažte nebo vyvraťte tvrzení. Pro každou dvojici funkcí f,g,f1,f2:N0R+f, g, f_1, f_2: N_0 \rightarrow \reals^+ platí:

  1. n2+6n+4=O(n2)n^2 + 6n + 4 = O(n^2)

    n2+6n+4O(n2)n^2 + 6n + 4 \in O(n^2)

    n2+6n+4cn2n^2 + 6n + 4 \le c \cdot n^2

    n2+6n+4n2c\frac{n^2 + 6n + 4}{n^2} \le c

    1+6n+4n2c1 + \frac 6 n + \frac{4}{n^2} \le c

    Platí např. pro c=10c = 10, s tím, že n0=1n_0 = 1

  2. n3=O(n2)n^3 = O(n^2)

    n3cn2n^3 \le c \cdot n^2

    n3n2c\frac{n^3}{n^2} \le c

    ncn \le c neplatí, protože ať vybereme pro zvětšující se nn jakkoliv velké cc, vždy bude existovat n>cn > c => nekonečný počet výjimek => vyvráceno

  3. Pokud f(n)=O(g(n))f(n) = O(g(n)), pak 2f(n)=O(2g(n))2^{f(n)} = O(2^{g(n)})

    f(n)O(g(n))    2f(n)O(2g(n))f(n) \in O(g(n)) \implies 2^{f(n)} \in O(2^{g(n)})

    Dosaďme tam např. f(n)=2nf(n) = 2n, a g(n)=ng(n) = n. Levá strana platí:

    2ncn2n \le c \cdot n

    2c2 \le c, platí

    Pravá strana neplatí:

    22nc22n2^{2n} \le c_2 \cdot 2^n

    22n2nc2\frac{2^{2n}}{2^n} \le c_2

    2nc22^n \le c_2 neplatí, protože ať už pro rostoucí 2n2^n vybereme jakékoli c2c_2, vždy bude existovat 2n>c22^n > c_2 => nekonečný počet výjimek => neplatí

    Když neplatí pravá strana implikace, implikace neplatí.

  4. f(n)=O(f(n)2)f(n) = O(f(n)^2)

    f(n)O(f(n)2)f(n) \in O(f(n)^2)

    Tohle je chyták!!! Přestože se v informatice u složitosti běžně nesetkáváme s klesajícími funkcemi, může f(n)f(n) zde být klesající (protože ff je pouze nějaké f:N0R+f: N_0 \rightarrow \reals^+, nevíme o něm nic víc), a pak tvrzení platit nebude.

    Například předpokládejme, že f(n)=1nf(n) = \frac 1 n:

    1nc1n2\frac 1 n \le c \cdot \frac{1}{n^2}

    ncn \le c => spor, viz úloha 2., vždy lze nalézt n>cn > c

    Tvrzení neplatí.

  5. Nechť f(n)=f1(n)+f2(n)f(n) = f_1(n) + f_2(n) a f1(n)=O(f2(n))f_1(n) = O(f_2(n)). Pak f(n)=O(f2(n))f(n) = O(f_2(n))

    f(n)=f1(n)+f2(n)f1(n)O(f2(n))    f(n)O(f2(n))f(n) = f_1(n) + f_2(n) \land f_1(n) \in O(f_2(n)) \implies f(n) \in O(f_2(n))

    pro n>n0n > n_0:

    f1(n)O(f2(n))f_1(n) \in O(f_2(n))

    f1(n)c1f2(n)f_1(n) \le c_1 \cdot f_2(n)

    Teď jelikož f(n)=f1(n)+f2(n)f(n) = f_1(n) + f_2(n), tak přičteme k oběma stranám f2(n)f_2(n):

    f1(n)+f2(n)c1f2(n)+f2(n)f_1(n) + f_2(n) \le c_1 \cdot f_2(n) + f_2(n)

    f1(n)+f2(n)(c1+1)f2(n)f_1(n) + f_2(n) \le (c_1 + 1) \cdot f_2(n)

    f1(n)+f2(n)cf2(n)f_1(n) + f_2(n) \le c \cdot f_2(n)

    f(n)cf2(n)f(n) \le c \cdot f_2(n)

    f(n)O(f2(n))f(n) \in O(f_2(n))

    Platí.

  6. Nechť f1f_1 a f2f_2 jsou funkce, pro které platí f1(n)=O(g(n))f_1(n) = O(g(n)) a f2(n)=O(g(n))f_2(n) = O(g(n)). Potom f1(n)+f2(n)=O(g(n))f_1(n) + f_2(n) = O(g(n))

    f1(n)O(g(n))f2(n)O(g(n))    f1(n)+f2(n)O(g(n))f_1(n) \in O(g(n)) \land f_2(n) \in O(g(n)) \implies f_1(n) + f_2(n) \in O(g(n))

    pro n>n01n > n_{0_1} platí: f1(n)c1g(n)f_1(n) \le c_1 \cdot g(n)

    pro n>n02n > n_{0_2} platí: f2(n)c2g(n)f_2(n) \le c_2 \cdot g(n)

    Všimněme si, že platnost těchto 2 nerovnic začíná od různých konstant. Když tedy budeme chtít něco trvdit pro obě zároveň, tedy například v f1(n)+f2(n)g(n)f_1(n) + f_2(n) \le g(n), tak bychom měli provést průnik intervalů [n01,)[n_{0_1}, \infty) a [n02,)[n_{0_2}, \infty). Tedy zvolit maximum z těch dvou.

    n0n_0 je \ge max{n01,n02}\max\{n_{0_1}, n_{0_2}\}, abychom tedy splnili podmínku o konečném množství výjimek.

    pro n0max{n01,n02}n_0 \ge \max\{n_{0_1}, n_{0_2}\}:

    f1(n)+f2(n)cg(n)f_1(n) + f_2(n) \le c \cdot g(n)

    c1g(n)+c2g(n)cg(n)c_1 \cdot g(n) + c_2 \cdot g(n) \le c \cdot g(n)

    c1+c2cc_1 + c_2 \le c => vždy najdeme konstantu větší než součet 2 jiných

  7. Nechť f1f_1 a f2f_2 jsou funkce, pro které platí f1(n)=O(g1(n))f_1(n) = O(g_1(n)) a f2(n)=O(g2(n))f_2(n) = O(g_2(n)). Potom f1(n)f2(n)=O(g1(n)g2(n))f_1(n) \cdot f_2(n) = O(g_1(n) \cdot g_2(n))

    f1(n)O(g1(n))f2(n)O(g2(n))    f1(n)f2(n)=O(g1(n)g2(n))f_1(n) \in O(g_1(n)) \land f_2(n) \in O(g_2(n)) \implies f_1(n) \cdot f_2(n) = O(g_1(n) \cdot g_2(n))

    pro nn1n \ge n_1: f1(n)c1g1(n)f_1(n) \le c_1 \cdot g_1(n)

    pro nn2n \ge n_2: f2(n)c2g2(n)f_2(n) \le c_2 \cdot g_2(n)

    Pokud na levé straně implikace má platit obojí současně, tak pro nmax{n1,n2}n \ge \max\{n_1, n_2\}.

    Pravá strana pak též pro nmax{n1,n2}n \ge \max\{n_1, n_2\}:

    f1(n)f2(n)=O(g1(n)g2(n))f_1(n) \cdot f_2(n) = O(g_1(n) \cdot g_2(n))

    f1(n)f2(n)g1(n)g2(n)f_1(n) \cdot f_2(n) \le g_1(n) \cdot g_2(n)

    Dosadíme levou stranu (násobit, dělit beze změny znaménka nerovnosti můžeme protože z definice c,g1,g2c, g_1, g_2 víme, že se jedná o kladná čísla (kladná konstanta a zobrazení do R+\reals^+)):

    (c1g1(n))(c2g2(n))g1(n)g2(n)(c_1 \cdot g_1(n)) \cdot (c_2 \cdot g_2(n)) \le g_1(n) \cdot g_2(n)

    c1c2cc_1 \cdot c_2 \le c => platí, vždy lze najít konstantu, která je \ge součinu 2 čísel.

    Lze postupovat i 2. způsobem: nerovnice f1(n)f2(n)=O(g1(n)g2(n))f_1(n) \cdot f_2(n) = O(g_1(n) \cdot g_2(n)) a f1(n)f2(n)g1(n)g2(n)f_1(n) \cdot f_2(n) \le g_1(n) \cdot g_2(n) spolu vynásobíme (můžeme protože z definice c,g1,g2c, g_1, g_2 víme, že se jedná o kladná čísla):

    f1(n)f2(n)c1g1(n)c2g2(n)f_1(n) \cdot f_2(n) \le c_1 \cdot g_1(n) \cdot c_2 \cdot g_2(n)

    f1(n)f2(n)(c1c2)c v cıˊleneˊ rovnicig1(n)g2(n)f_1(n) \cdot f_2(n) \le \underbrace{(c_1 \cdot c_2)}_{c\text{ v cílené rovnici}} \cdot g_1(n) \cdot g_2(n)

    c1c2c_1 \cdot c_2 je člen cc v cílené rovnici (té, kam se snažíme v důkazu dojít), tedy c=c1c2\exists c = c_1 \cdot c_2, aby nerovnosti a tedy i tvrzení platily.

  8. f=O(g)f = O(g) potom g=Ω(f)g = \Omega(f)

    f(n)Ω(g(n))    cR+ n0N nn0:f(n)cg(n)f(n) \in \Omega(g(n)) \iff \exists c \in \reals^+ \ \exists n_0 \in \natnums \ \forall n \ge n_0: f(n) \ge c \cdot g(n)

    Tedy stejná definice jako pro O(g(n))O(g(n)), ale otočené znaménko nerovnosti.

    pro n>n0n > n_0:

    f(n)O(g(n))    g(n)Ω(f(n))f(n) \in O(g(n)) \implies g(n) \in \Omega(f(n))

    levá strana:

    f(n)O(g(n))f(n) \in O(g(n))

    f(n)c1g(n)f(n) \le c_1 \cdot g(n)

    f(n)1c1g(n)f(n) \cdot \frac{1}{c_1} \le g(n)

    g(n)f(n)1c1g(n) \ge f(n) \cdot \frac{1}{c_1}

    pravá strana:

    g(n)Ω(f(n))g(n) \in \Omega(f(n))

    g(n)cf(n)g(n) \ge c \cdot f(n)

    Takže máme:

    g(n)1c1f(n)    g(n)cf(n)g(n) \ge \frac{1}{c_1} \cdot f(n) \implies g(n) \ge c \cdot f(n)

    A to už platí, protože je to vlastně stejná nerovnost. Vždy lzde stanovit c1c_1 resp. c2c_2 tak aby platilo 1c1=c2\frac{1}{c_1} = c_2 a platí pro stejná nn jako f(n)O(g(n))f(n) \in O(g(n)).


Ještě pár příkladů, tentokrát z Průvodce (2.4 Asymptotická notace, str. 51). Ty už ovšem nikým oveřené nejsou.

Ještě definice:

Řekněme, že funkce f(n)f(n) je třídy Θ(g(n))\Theta(g(n)), jestliže f(n)f(n) je jak třídy O(g(n))O(g(n)), tak třídy Ω(g(n))\Omega(g(n)).

Symboly Ω\Omega a Θ\Theta opět mohou značit i příslušné množiny funkcí. Pak jistě platí Θ(g)=O(g)Ω(g)\Theta(g) = O(g) \cap \Omega(g)

  1. Nalezněte co nejvíc asymptotických vztahů mezi těmito funkcemi nn, logn\log n, loglogn\log \log n, n\sqrt{n}, nlognn^{\log n} , 2n2^n, n3/2n^{3/2}, n!n!, nnn^n.

    (jelikož jsme v informatice, tak ty logaritmy uvažujeme o základu 2, ale to je jedno - logaritmus o základu 10 se liší konstanta krát)

    Třeba log(n)O(n)\log(n) \in O(n). Mohli bychom se podívat na grafy y=log2(x)y = \log_2(x) a y=ny = n, a říct, že to je zcela zřejmé, ale pokud bychom to chtěli formálně, a neumíme nic z analýzy, tak to můžeme udělat indukcí.

    log2(n)O(n)\log_2(n) \in O(n)

    log2(n)cn\log_2(n) \le c \cdot n

    Konstanta cc existuje, př. to můžeme ukázat pro c=1c = 1. A n0=1n_0 = 1.

    n=1n = 1: log2(1)1\log_2(1) \le 1 = 010 \le 1, platí

    Chceme ukázat, že z n=kn = k: log2(k)k\log_2(k) \le k plyne n=k+1n = k+1: log2(k+1)k+1\log_2(k+1) \le k + 1.

    Logaritmus je funkce rostoucí, tudíž můžeme říct, že:

    log2(k+1)log2(2k)\log_2(k+1) \le \log_2(2k), protože 2k>k+12k > k + 1 pro k1k \ge 1

    log2(2k)=log2(k)+log2(2)=log2(k)+1\log_2(2k) = \log_2(k) + \log_2(2) = \log_2(k) + 1

    log2(k+1)log2(k)+1\log_2(k+1) \le \log_2(k) + 1

    A teď využijeme indukčního předpokladu, dosadíme za log2(k)\log_2(k) výraz, který je větší nebo roven:

    log2(k+1)k+1\log_2(k+1) \le k + 1

    To je to, k čemu jsme se chtěli dostat.

4. Dokažte, že nlognO(n)n \log n \notin O(n):

nlognO(n)n \log n \in O(n)

nlogncnn \log n \le c \cdot n

lognc\log n \le c => neplatí, my jsme však chtěli nlognO(n)n \log n \notin O(n), tak to platí:

Tedy:

nlognO(n)n \log n \notin O(n)

nlogn>cnn \log n > c \cdot n

logn>c\log n > c => platí