re,
kicsit off voltam nyáron. Nemsokára folytatom a regexes threadet is (remélem), addig is elkezdek itt egy bonyelm gyakjegyzetet loggolni :-)
Első jóhír, hogy jótanácsot követve belőttem a MathJaxet, úgyhogy most már talán ki fognak nézni valahogy a matekos jelek is.
Első gyakorlaton (követelményismertetés után ofc) felidéztük, hogy futásidőket és tárigényeket akarunk majd összehasonlítani és számolgatni, ezeket pedig elég lesz csak nagyságrendben ismernünk, nem a pontos függvényeket. Ha f, g függvények (mondjuk természetes számokat valós számokra képezőek, de lehet az értelmezési tartomány is a pozitív valós, vagy az értékkészlet a természetes, mindegy), akkor azt mondjuk, hogy f=O(g) (ami kb. a "g legalább olyan gyorsan nő, mint f"-nek felel meg), ha van olyan c>0 konstans, amire f≤c⋅g(n) majdnem minden n-re (ami matekul ugyanaz, mint hogy "van olyan N küszöbszám, hogy ha n>N, akkor már igaz).
- Például, 3n=O(n2100), mert ha c=100 és N=3, akkor tényleg fennáll, hogy ha n>3, akkor 3n≤100⋅n2100=n2 (egyszerűsítünk n-nel, kész).
Az O (e. ordó) kapcsolatnál szigorúbb az o (kisordó) kapcsolat: f=o(g), ha tetszőleges c>0-ra f(n)≤c⋅g(n) majdnem minden n-re. (Ez kb. a "g gyorsabban nő, mint f"-nek felel meg.) Ilyenkor már nem mondani kell egy c-t és egy N-t, hanem tetszőleges c>0-ra mondani kell egy N-t, amitől kezdve igaz az összefüggés.
- Például, 3n=o(n2100) is igaz, hiszen ha c>0, akkor átrendezve kapjuk, hogy ha 300c≤n, akkor 3n≤c⋅n2100.
Ezután megláttuk a log2n=o(n) feladatot.. hát erre input c>0 küszöbszámra mondani megfelelő N-t már nem nekünk való feladvány (megjegyzés: a log mindig kettes alapú logaritmust jelent, mi mást, a log2n pedig a (logn)2-nek egy átláthatóbb formája. Nem pedig pl. a loglogn-nek). Szerencsére "tudjuk", hogy ha limn→∞f(n)g(n)=0, akkor f=o(g). Ha pedig a limesz legalábbis kisebb, mint végtelen (tehát például 7, 0 vagy π), akkor f=O(g) lesz.
Ezután már könnyű volt, mert limn→∞log2nn a L'Hopital-szabály szerint ugyanannyi, mint limn→∞2⋅ln2⋅lognn, ami megint ugyanemiatt a szabály miatt limn→∞2⋅ln2⋅ln2n, ami tényleg 0, tehát log2n=o(n). Persze akármilyen k>0 konstanst is mondunk, ezek szerint logk(n)=o(n) is igaz lesz - ez nálunk annyit tesz, hogy akár futásidőről, akár tárigényről lesz szó, a logk(n) alakú erőforrás-igényt jobbnak fogjuk tartani, mint a lineárist. (A logk(n) alakú függvényeket egyébként polilogaritmikus függvénynek hívjuk.) Persze ha szekvenciális algoritmusról beszélünk, annak nem lehet o(n) (amit szublineárisnak is mondunk) az időigénye, hiszen ennyi lépésben nem tudja végigolvasni se az inputot. Amikor elő fognak jönni szublineáris függvények:
- tárigénynél;
- párhuzamos számítás időigényénél.
Megnéztük még azt is, hogy n2=o(2n), hiszen két L'Hopital szabály után kapjuk, hogy limn22n=lim2nln2⋅2n=lim2ln2ln2⋅2n=0. Általában is igaz, hogy ha p polinom, e pedig exponenciális függvény, akkor p=o(e), legyen akármekkora a polinom fokszáma és akármilyen pici is az e alapja. Általában futásidőről ha szó lesz, akkor a polinomnak fogunk örülni, azt tekintjük hatékony algoritmusnak, ami polinom időigényű (legrosszabb esetben is), és egy problémát hatékonyan megoldhatónak akkor hívjuk, ha van rá polinom időigényű algoritmus. (Ez a Cobham-Edmonds tézis.)
Házi jelleggel megnézhetjük, hogy az exponenciális lassabban nő, mint n!, ami pedig lassabb, mint a 2n2.
No comments:
Post a Comment