Az előadás letöltése folymat van. Kérjük, várjon

Az előadás letöltése folymat van. Kérjük, várjon

Dinamikus fák és utak Készítette: Kovács Péter 2008.06.27.

Hasonló előadás


Az előadások a következő témára: "Dinamikus fák és utak Készítette: Kovács Péter 2008.06.27."— Előadás másolata:

1 Dinamikus fák és utak Készítette: Kovács Péter 2008.06.27. Email: kpeter@inf.elte.hu

2 Dinamikus fák  Különböző hálózati algoritmusokban gyakran van szükség dinamikusan változó fák kezelésére.  Erre a feladatra bemutatunk egy hatékony adatszerkezetet. 2  Feladat:  Tároljuk csúcsdiszjunkt gyökeres fák egy erdejét. (A fákra szerkezeti megkötés nincs.)  Minden csúcshoz tároljunk egy valós költséget (cost).  Valósítsuk meg minél hatékonyabban az alábbi műveleteket:  maketree(v)  parent(v), cost(v)  findroot(v), findcost(v), addcost(v, x)  link(v, w), cut(v)  Cél: minél jobb amortizációs időt (≈ átlagos időt) elérni egy műveletsorozat végrehajtása során.

3 Dinamikus fa műveletek  maketree(v): egy csúcsból álló fa létrehozása (v költsége 0 lesz)  parent(v), cost(v):  Egy csúcsra vonatkozó műveletek.  A v csúcs szülőjének és költségének lekérdezése. 3 findroot(v)  findroot(v), findcost(v), addcost(v):  A v csúcstól a gyökérig vezető útra vonatkozó műveletek.  findroot(v): a v csúcsot tartalmazó fa gyökércsúcsának megkeresése.  findcost(v): az úton a minimális költségű csúcs megkeresése (ha több ilyen is van, akkor az utolsót, vagyis a legfelsőt kell megadni).  addcost(v, x): az úton minden csúcs költségének növelése x-szel. v

4 Dinamikus fa műveletek  Az eddigiek valójában statikus műveletek voltak. 4  link(v, w), cut(v):  Dinamikus műveletek, amelyek megváltoztatják a fák szerkezetét.  link(v, w):  A v és w csúcsokat tartalmazó fák összekapcsolása.  v mindig egy fa gyökere, amelyet w-hez kapcsolunk egy (v,w) él hozzáadásával.  A fák éleit mindig fölfelé (a szülő felé) irányítottnak tekintjük.  cut(v):  A v csúcsot tartalmazó fa szétvágása két részfára a v-ből kivezető él törlésével. v w v

5 Dinamikus fák megvalósítása  Egyszerű megvalósítás:  Minden csúcshoz tároljuk a szülőjére mutató pointert és a költségét.  maketree(v), parent(v), cost(v) műveletek:O(1)  link(v, w), cut(v) műveletek:O(1)  findroot(v), findcost(v), addcost(v, x) műveletek:O(n) (a v csúcs mélységével arányos futási idő, ami legrosszabb esetben O(n).)  Cél:  Ennél hatékonyabbat adni.  Minden művelet (átlagos) ideje O(log n) legyen.  Analógia:  Prioritásos sor megvalósítása (pl. Dijkstra, Prim stb. algoritmusokhoz): rendezetlen/rendezett tömb  (bináris) kupac  Szótár megvalósítása (keresés, beszúrás, törlés műveletek): tömb/lista  kiegyensúlyozott keresőfa (pl. AVL-fa) 5

6 Dinamikus fák megvalósítása  Ötlet:  A fákat implicit módon tároljuk.  Minden fát szétbontunk csúcsdiszjunkt utakra és azokat összekötő élekre.  Később bemutatunk egy olyan adatszerkezetet, amellyel a szükséges műveletek utakra hatékonyan elvégezhetők.  Ezt felhasználva a faműveleteket útműveletekkel valósítjuk meg. 6

7 Fák felbontása utakra  Az éleket két csoportba soroljuk:  erős élek:  gyenge élek:  Egy csúcsba legfeljebb egy erős él vezethet.  Ezzel a fákat csúcsdiszjunkt erős utakra particionáljuk.  Lehetnek egy csúcsból álló erős utak is.  Tárolás:  Tároljuk az erős utakat (l. később).  Minden úthoz egy rákövetkező (successor) csúcsot: ahova az út végpontjából kiinduló gyenge él vezet.  Az aktuális felbontás a műveletek hatására folyamatosan változik! 7

8 Egy út kiemelése  Szükségünk van még egy fontos műveletre.  expose(v):  A v csúcsból a gyökérbe vezető út kiemelése.  Megváltoztatjuk az élek aktuális erős-gyenge felosztását oly módon, hogy ez egy erős út legyen.  Az út minden éle erős él lesz, és v-be nem vezet erős él. 8 vv

9 Egy út kiemelése  expose(v) megvalósítása: 9 function expose(node v): path; p := null; while v  null w := successor(path_find(v)); (q,r) := path_split(v); if q  null then successor(q) := v; p := path_concat(p,v,r); v := w; end while successor(p) := null; return p; end expose;

10 Műveletek megvalósítása  maketree(v), parent(v), cost(v): a megfelelő faművelet meghívása (csak a v csúcsot érinti).  findroot(v), findcost(v), addcost(v, x):  Először expose(v): a v csúcstól a gyökérig vezető út kiemelése, a tárolás megváltoztatása.  Utána a megfelelő faművelet végrehajtása. function findcost(node v): real; return path_findcost(expose(v)); end findcost; function findroot(node v): node; return path_findtail(expose(v)); end findroot; procedure addcost(node v, real x); path_addcost(expose(v)); end addcost; function findroot(node v): node; p := expose(v); return path_findtail(p); end findroot; 10

11 Műveletek megvalósítása  link(v, w), cut(v):  Hasonlóan: expose(v), utána a megfelelő faművelet végrehajtása, és a successor mutatók beállítása. 11 procedure link(node v, w); p := path_concat(null, expose(v), expose(w)); successor(p) := null; end link; procedure cut(node v); expose(v); (p,q) := path_split(v);// p üres lesz successor(v) := null; successor(q) := null; end link;

12 Elemzés  A faműveletek meghatározó lépései:  a különböző útműveletek;  az expose(v) hívások, amelyek szintén útműveleteket hajtanak végre.  Belátható, hogy m faművelet végrehajtása során:  a path_concat és path_split műveletek száma O(m log n),  a többi útművelet száma O(m).  A következőkben pedig bemutatunk egy hatékony adatszerkezetet utak kezelésére, amellyel:  az összes path_concat és path_split művelet megvalósítható O(m log n) időben,  a többi útművelet pedig külön-külön O(log n) időben.  Tehát:  Az O(m) faművelet O(m log n) időben végrehajtható.  Egy faművelet amortizált futási ideje O(log n). 12

13 Dinamikus utak  A vizsgált adatstruktúra megvalósításához „dinamikus utak” hatékony kezelése szükséges.  Műveletek:  path_make(v): egyelemű út létrehozása a v csúcsból (0 költséggel).  path_find(v): a v csúcsot tartalmazó út meghatározása.  path_findtail(p): a p út végpontjának megkeresése.  path_cost(v): a v csúcs költsége.  path_findcost(p): a p úton a minimális költségű csúcs megkeresése (ha több ilyen is van, akkor az utolsót kell megadni).  path_addcost(p,x): a p úton minden csúcs költségének növelése x-szel.  path_concat(p,v,q): a p és q utak összekapcsolása (konkatenálása) a v csúcs közbeiktatásával.  path_split(v): a v csúcsot tartalmazó út szétvágása a v-hez kapcsolódó élek törlésével. 13 p q v v

14 Dinamikus utak reprezentálása  A továbbiakban dinamikus utak kezelésére adunk egy hatékony adatstruktúrát.  Egy utat reprezentáljunk egy gyökeres bináris fával úgy, hogy:  A fa csúcsai inorder sorrendben az út csúcsait adják.  Egy belső csúcs egy részútnak feleltethető meg.  A gyökércsúcs reprezentálja a teljes utat. 14 abcdefg a b c d e f g

15 Dinamikus utak reprezentálása  Valamilyen módszerrel biztosítjuk a bináris fa kiegyensúlyozottságát.  Így a műveleteket többségét el tudjuk végezni O(log n) időben.  A nehézséget a költségek kezelése okozza.  Szükséges műveletek:  path_findcost(p): a minimális költségű csúcs megkeresése.  path_addcost(p,x): minden csúcs költségének növelése x-szel.  A triviális megvalósítással (minden csúcshoz tároljuk a költségét) ezek csak O(n) időben hajthatók végre.  Ötlet:  A költségeket implicit módon tároljuk.  Az egyes csúcsokra és részfákra vonatkozó költségértékek különbségeit tároljuk csúcsonként.  Így egy csúcshoz tartozó részfa (részút) minimális költsége megadható O(1) időben, a minimális költségű csúcs pedig O(log n) időben. 15

16 Költségek kezelése  Jelölje cost(x) az x költségét, mincost(x) pedig az x-hez tartozó részfa csúcsai költségének minimumát.  Minden x csúcshoz tároljuk a Δcost(x) és Δmin(x) értékeket:  Δcost(x): az x költségének eltérése az x-hez tartozó részfa minimális költségétől. Δcost(x) = cost(x) – mincost(x)  Δmin(x): az x-hez és a szülőjéhez tartozó részfa minimális költségének különbsége. Δmin(x) = mincost(x) – mincost(parent(x))ha x nem gyökér Δmin(x) = mincost(x)ha x gyökér  Δcost(x) ≥ 0 minden x csúcsra, és Δmin(x) ≥ 0 minden nem gyökér x csúcsra.  Ilyenkor mincost(x) meghatározható úgy, hogy a Δmin értékeket összeadjuk a bináris fa gyökerétől x-ig vezető úton.  Ebből pedig cost(x) megkapható így: cost(x) = mincost(x) + Δcost(x). 16

17 Költségek kezelése  Példa: 17 b (3) a (6)f (2) g (7)d (5) c (4) e (8) b (2,1) a (4,0)f (0,0) g (5,0)d (2,1) c (0,0)e (4,0) x ( cost(x) ) x ( Δmin(x), Δcost(x) )

18 Költségek kezelése  path_findcost(p):  A bemutatott implicit tárolással egy út (bináris fa) csúcsai költségeinek minimumát 1 lépésben meg tudjuk adni.  Egy minimális költségű csúcsot pedig kereshetünk a következőképpen:  Induljunk el a gyökérből, és lépkedjünk lefelé.  Mindig azt az irányt válasszuk, ahol Δmin(x) = 0. Ha ez mindkét gyerekre igaz, akkor lépjünk jobbra (mert az utolsó jó csúcs kell nekünk).  Akkor állunk meg, ha a Δcost érték is 0 lesz, és nincs jobb gyerek, vagy annak Δmin értéke nem 0.  path_addcost(p,x):  Csak a gyökércsúcs Δmin értékéhez kell hozzáadni x-et. (O(1) idejű!)  Ugyanis minden költséget ahhoz viszonyítva számolunk.  Vagyis egy csúcs költségének lekérdezése O(1) helyett O(log n) idejű lett, cserébe viszont a fenti két művelet O(n) helyett O(log n). 18

19 Bináris fák kiegyensúlyozása  Fontos a bináris fák kiegyensúlyozottsága, amely a dinamikus műveletek (path_concat és path_split) hatására elromolhat.  Egy egyszerű forgatás O(1) időben megvalósítható (a Δcost és Δmin értékeket is módosítani kell!).  Forgatásokkal biztosíthatjuk a fa kiegyensúlyozottságát úgy, ahogy a keresőfáknál (AVL-fa, piros-fekete fa, önkiegyensúlyozó fa stb.).  Így minden útműveletre garantálható az O(log n) korlát.  Most térjünk vissza a dinamikus fákra adott struktúrához.  m faművelethez O(m log n) útművelet kellett, ami ezek alapján O(m (log n) 2 ) idő.  Ha az utak megvalósításához önkiegyensúlyozó fákat használunk, akkor ennél egy log n faktorral jobb lépésszámkorlát adható.  Vagyis az O(m log n) path_concat és path_split művelet összesen csak O(m log n) lépés, amit korábban ígértünk. 19

20 Megjegyzések  Mivel egy utat egyértelműen meghatároz az őt reprezentáló bináris fa gyökere, az útra vonatkozó successor mutatót tárolhatjuk ennél a csúcsnál.  A bemutatott dinamikus fa adatszerkezetnek több más változata is ismert:  Az adatszerkezet kiegészíthető további műveletekkel.  Az utakra bontást bonyolultabban végezve elérhető, hogy minden műveletre külön teljesüljön az O(log n) korlát.  Van olyan változat, amelyben az éleknek van költsége, nem a csúcsoknak. Ilyenkor bonyolultabb bináris keresőfákat kell alkalmazni az utak reprezentálására. 20

21 Felhasznált irodalom  Robert E. Tarjan: Data Structures and Network Algorithms. Society for Industrial and Applied Mathematics, 1983.  Daniel D. Sleator – Robert E. Tarjan: A Data Structure for Dynamic Trees. Journal of Computer and System Siences, 26(3):362-391, 1983.  Ravindra K. Ahuja – Thomas L. Magnanti – James B. Orlin: Network Flows: Theory, Algorithms, and Applications. Prentice-Hall, Inc., 1993. 21


Letölteni ppt "Dinamikus fák és utak Készítette: Kovács Péter 2008.06.27."

Hasonló előadás


Google Hirdetések