Mediánok és rendezett minták
Rendezett minta Egy n elemű halmaz esetén a rendezett minta i-edik eleme a halmaz i-edik legkisebb eleme. i = 1, a halmaz rendezett mintájának első eleme a halmaz minimuma i = n, a rendezett minta utolsó eleme a halmaz maximuma A medián a halmaz „középpontja”. Ha n páratlan egyetlen medián: i = (n + 1)/2 Ha n páros két medián: i = n/2 és i = n/2 + 1 Alsó medián: i = (n + 1)/2 pozícióban Felső medián: i = (n + 1)/2 pozícióban A továbbiakban medián alatt az alsó mediánt értjük.
Miről lesz szó? Hogyan választjuk ki az n különböző számot tartalmazó halmazból a rendezett minta i. elemét anélkül, hogy rendeznénk? Egy halmaz minimumának és maximumának kiválasztási problémája. Az általános kiválasztási feladat. Gyakorlati algoritmus, amelynek az átlagos futási ideje – különböző elemeket feltételezve – O(n). Egy elméleti szempontból érdekes algoritmus, amelynek O(n) a legrosszabb futási ideje.
A kiválasztási feladat Bemenet: Az n (különböző) számból álló A halmaz és az 1 i n szám. Kimenet: Az x A elem, amelyik nagyobb, mint az A pontosan i – 1 másik eleme. Naiv algoritmus Rendezzük az elemeket kupacrendezéssel vagy összefésülő rendezéssel, majd a kimeneti tömbben rámutatunk az i-edik elemre. a kiválasztási feladat O(n lg n) időben megoldható. Léteznek ennél gyorsabb algoritmusok is!
Minimum és maximum egyidejű meghatározása Naiv algoritmus: aszimptotikusan (n) számú összehasonlítást használ. Ha a minimumot és a maximumot egymástól függetlenül keressük, mindegyikhez n – 1 összehasonlítást használunk, ez összesen 2n – 2 összehasonlítás. A minimum és maximum egyidejű meghatározásához valójában elég mindössze 3n/2 összehasonlítás!!!
Naiv algoritmus Algoritmus Minimum(n, a): 1 min a1 2 Minden i=2,n végezd el: 3 Ha min > ai akkor 4 min ai vége(ha) vége(minden) Vége(algoritmus)
Állítás Az előbbi algoritmus optimális. Bizonyítás Ki fogjuk mutatni, az indukciót használva, hogy bármely, összehasonlításokra épülő algoritmus legkevesebb n – 1 műveletet végez. Ha n = 1, nem végzünk egyetlen összehasonlítást sem. Feltételezzük, hogy bármely algoritmus, amely megoldja a feladatot n szám esetében, legfeljebb n – 1 összehasonlítást végez, és tárgyaljuk azt a feladatot, amely n + 1 szám minimumát kéri. Legyen az első összehasonlítás, amely (anélkül, hogy vesztenénk az általánosságból) összehasonlítja a1-t a2-vel, és megállapítja, hogy a1 < a2.
Bizonyítás A továbbiakban meg kell oldanunk a feladatot az (a1, a3, ..., an+1) sorozat esetében. De ezt a feladatot (a sorozatnak n eleme van) n – 1 összehasonlítással végeztük, tehát az n + 1 elemű sorozat minimumát összesen n összehasonlítás után kaptuk meg. Visszatérünk a minimum és maximum egyidejű meghatározásához: az algoritmus minden lépésében megőrizzük a megvizsgált elemek minimumát és maximumát. elempárokat hasonlítunk össze. ezeket először egymással hasonlítjuk össze, majd a kisebbiket az aktuális minimum értékkel, a nagyobbikat az aktuális maximum értékével hasonlítjuk össze, ez költségben három összehasonlítást jelent két elemre nézve.
Minimum és maximum egyidejű meghatározása Ha n páratlan, a minimális és maximális érték kezdőértéke az első elem értéke lesz, és páronként dolgozzuk fel a maradék elemeket. Ha n páros, az első két elemen egy összehasonlítást végzünk a minimum és a maximum kezdőértékének meghatározása céljából, majd, mint a páratlan n esetén párokban dolgozzuk fel a maradék elemeket. Az összehasonlítások száma: 3n/2
Kiválasztás átlagosan lineáris időben A kiválasztási feladat oszd meg és uralkodj elvű algoritmusa következik: A Véletlen_Kiválaszt(a, bal, jobb, i) eljárás a véletlenített gyorsrendezés mintájára épül. A bemeneti tömböt rekurzív módon felosztjuk és a felosztásnak csak az egyik felével dolgozunk tovább. Amíg a gyorsrendezés átlagos futási ideje (n lg n), addig a Véletlen_Kiválaszt(a, bal, jobb, i) átlagos futási ideje (n).
Kiválasztás átlagosan lineáris időben A Véletlen_Kiválaszt(a, bal, jobb, i) az abal, ..., ajobb tömb i-edik legkisebb elemét adja vissza. A Véletlen_Kiválaszt(a, bal, jobb, i) a Véletlen_Feloszt(a, bal, jobb, m) eljárást használja. Emlékezzünk: Algoritmus Véletlen_Feloszt(a, bal, jobb, m): i Véletlen(bal,jobb){ Random bal és jobb között } Csere(ajobb,ai) Feloszt(a,bal,jobb,m) Vége(algoritmus)
Algoritmus Véletlen_Kiválaszt(a,bal,jobb,i): { az i-edik legkisebb elemet keressük } Ha bal = jobb akkor visszatérítjük abal-t vége(ha) m Véletlen_Feloszt(a, bal, jobb) { m index bal és jobb között } k m - bal + 1 { az őrszem a k-adik legkisebb elem } Ha i = k akkor { az őrszem elem egyben az i-edik } visszatérítjük am-t különben Ha i < k akkor { a keresett elem a felosztás bal részében van } Véletlen_Kiválaszt(a, bal, m-1, i) különben { a felosztás jobb részében található } Véletlen_Kiválaszt(a, m+1, jobb, i-k) Vége(algoritmus) Fontos!!! Fogalmazás formájában is!!!
A Véletlen_Feloszt(a, bal, jobb) végrehajtása után: abal, ..., ajobb = (abal, ..., am-1), + (am+1, ..., ajobb) abal, ..., am-1 am, és am am+1, ..., ajobb. Már k darab értékről tudjuk, hogy < mint az abal, ..., ajobb tömb i-edik legkisebb eleme a keresett elem az am+1, ..., ajobb tömb (i – k)-adik legkisebb eleme. m Véletlen_Feloszt(a, bal, jobb) k m - bal + 1 [m] [m] m bal m jobb őrszem
Példa Keressük a 7. legkisebb elemet bal = 1, jobb = 8, ha m = 4, k = 4, 7 > 4 (időközben az őrszemtől jobbra található az Am-nél minden nagyobb elem). Keressük (rekurzívan) a 7 – 4 = 3-dik legkisebb elemet a jobboldali sorozatban...
Intuitív elemzés Ha szerencsések vagyunk: nlog9/101 = n0 = 1 (Mester tétel: 3. eset) T(n) = T(9n/10) + Θ(n) = Θ(n) Ha pechesek vagyunk: T(n) = T(n – 1) + Θ(n) = Θ(n2) Rosszabb mint a rendezés!
Az algoritmus elemzése A Véletlen_Kiválaszt(a,bal,jobb,i) futási ideje legrosszabb esetben (n2). Előfordulhat, hogy annyira szélsőségesen nincs szerencsénk, hogy a felosztás minduntalan a legnagyobb megmaradó értékek körül történik és a felosztás (n) időt vesz igénybe. DE: Az algoritmus átlagos esetben jól teljesít, sőt, mivel véletlenített, nem létezik olyan bemenet, amelyik a legrosszabb viselkedésű esetet idézné elő.
Algoritmus Kiválaszt(i, n): lineáris időben (Fakultatív) 1. A bemeneti tömb n elemét felosztjuk n/5 darab 5 elemből álló csoportra. A maradék n mod 5 darab elem egy új csoportot alkot. 2. Megkeressük mindenik csoportnak a mediánját (a legfeljebb 5 elemet tartalmazó csoportokat beszúró rendezéssel rendezzük). Kiválasztjuk a mediánt a rendezett csoportból. 3. A Kiválaszt(i, n) algoritmus rekurzív használatával meghatározzuk az n/5 darab medián x mediánját.
Algoritmus Kiválaszt(i, n): 4. A módosított Feloszt algoritmus segítségével felosztjuk a bemeneti tömböt a mediánok mediánja, azaz x körül. Ha k a felosztás alsó részébe került elemek számánál 1-gyel nagyobb úgy, hogy x a k-dik legkisebb elem, akkor a felosztás felső részében n – k elem van. 5. Ha i = k, akkor a visszaadott érték legyen x. Máskülönben a Kiválaszt(i, n) algoritmus rekurzív használatával megkeressük: ha i k, akkor az alsó részben az i-edik legkisebb elemet, vagy ha i > k, akkor a felső részben az (i – k)-adik legkisebb elemet.
A kiválasztó elem meghatározása
A kiválasztó elem meghatározása 1. Felosztjuk a bemeneti tömb n elemét n/5 darab 5 elemből álló csoportra. A maradék n mod 5 darab elem egy új csoportot alkot.
A kiválasztó elem meghatározása kisebb 2. Megkeressük az 5 elemű csoportok mediánjait. nagyobb
A kiválasztó elem meghatározása kisebb 3. Meghatározzuk rekurzívan az n/5 darab medián x mediánját. nagyobb
Elemzés kisebb A csoportok mediánjainak legkevesebb fele ≤ x, ami legkevesebb n/5 /2 = n/10. nagyobb
Elemzés kisebb Tehát, legkevesebb 3n/10 elem ≤ x... nagyobb
Elemzés kisebb és legkevesebb 3n/10 elem ≥ x. nagyobb
A futási idő Minden n ≥ 50-re 3 n/10 ≥ n/4. Tehát az 5. lépésben (minden n ≥ 50-re) a Kiválaszt(i, n) rekurzívan kevesebb mint 3n/4 elemre hajtódik végre. Így az 5. lépés futási ideje a legrosszabb esetben T(3n/4). Ha n < 50, a legrosszabb futási idő T(n) = Θ(1). T(n) = 1. A bemeneti tömb felosztása 5 elemű csoportokra (n) + 2. A csoportok mediánjainak megkeresése (n) + 3. A Kiválaszt(i, n) algoritmus rekurzív használatával meghatározzuk az n/5 darab medián x mediánját T(n/5) + 4. A bemeneti tömb felosztása x körül (n) + 5. Ha i = k, akkor vissza x. Máskülönben megkeressük: ha i k, akkor az alsó részben az i-edik legkisebb elemet, vagy ha i > k, akkor a felső részben az (i – k)-adik legkisebb elemet T(3n/4)
Elemzés T(n) = (n) + (n) + T(n/5) + (n) + T(3n/4) = = T(n/5) + T(3n/4) + (n) Behelyettesítés: T(n) cn T(n) cn/5 + 3cn/4 + (n) = 19cn/20 + (n) = = cn – (cn/20 - (n)) cn ha c megfelelően nagy. De a véletlenített algoritmus a gyakorlatban sokkal jobb!