PUTEVI U GRAFU - nasport.pmf.ni.ac.rs

55
PUTEVI U GRAF U MINIMALNO RAZA PINJUĆE STABLO

Transcript of PUTEVI U GRAFU - nasport.pmf.ni.ac.rs

GRAFOVSKI ALGORITMIBFS za grafove sa razliitim duinama grana
Posmatrali smo BFS algoritam za grafove ije grane nemaju teinu (imaju iste duine).
To je prilino redak sluaj u primenama gde se trae najkrai putevi
eši su sluajevi kada grane imaju razliite teine (duine), kao u donjem primeru to ne mora da budu fizike duine, to moe biti vreme (potrebno da bi se prešao put), novac (cena autobuske karte ili goriva), ili bilo koja druga vrednost
Adaptacija BFS algoritma
Neka je dat graf = , kod koga je svakoj grani = (, ) ∈ pridruena duina koju oznaavamo sa (, ), ili
Neka su duine pozitivni celi brojevi
Adaptiraemo BFS za potrebe ovakvog algoritma:
svaku granu = (, ) ∈ zamenimo sa grana duine 1, dodajui − „lanih“ vorova izmeu i
Na ovaj nain dobijamo novi graf ′ koji sadri sve vorove iz i rastojanja izmeu njih su ista kao u , i moemo ih izraunati pokretanjem BFS na ′
Budilnik
Ako nam efikasnost algoritma nije vana, moemo se zaustaviti ovde.
Meutim, ako graf ima duge grane, graf ′ e imati veliki broj lanih vorova, i BFS e najvei deo svog radnog vremena potrošiti na izraunavanje rastojanja do nebitnih vorova, kao što je sluaj u sledeem primeru:
Šta nam je initi? Da li postoji li neki nain da dremamo dok prelazimo zamorni deo puta preko lanih vorova i da navijemo alarm koji e da nas probudi kada se desi nešto zanimljivo, kada stignemo do pravog vora?
Budilnik
Na primer, mogli bi da podesimo dva alarma na poetku, jedan za vor , podešen da se ukljui u vremenu = 100, a drugi za vor , podešen za vreme = 200.
To su procenjena vremena dolaska.
Kada nas alarm probudi u = 100 i otkrijemo , procenjeno vreme dolaska za prepodešavamo na = 150, jer smo tu u ustanovili da je vreme dolaska u prethodno bilo precenjeno.
Budilnik
Sledei „alarm clock algoritam“ verno simulira izvršavanje BFS na grafu ′ :
podešavamo alarm za vor na vreme 0
ponavljamo sledee sve dok više ne bude alarma:
recimo da se sledei alarm ukljuuje u vreme , za vor . Tada
rastojanje od do je
za svakog suseda od radimo sledee: ako još uvek nije bilo alarma za , podesimo ga na + (, )
ako je alarm za podešen za vreme kasnije od + (, ), prepodesimo ga na to ranije vreme
Dijkstrin algoritam
Da bi nam algoritam bio gotov, treba samo da vidimo kako da implementiramo sistem alarma.
Struktura podataka pogodna za to je kju prioriteta (priority queue)
Kju prioriteta je skup elemenata (u ovom sluaju vorovi) sa pridruenim numerikim kljunim vrednostima (u ovom sluaju vremena alarma)
Kju prioriteta dozvoljava sledee operacije:
Insert dodaje novi element u skup
Decrease-key smanjuje kljunu vrednost posebnog elementa
Delete-min izdvaja element sa najmanjom kljunom vrednošu i uklanja ga iz skupa
Make-queue izgrauje kju prioriteta iz datih elemenata, sa datim kljunim vrednostima (u mnogim primenama to je znatno bre nego unošenje elemenata jedan po jedan)
Dijkstrin algoritam najkraeg puta (Dijkstra's shortest-path algorithm)
predstavlja trenutnu vrednost vremena alarma, a ∞ znai da alarm još uvek nije podešen
pokaziva koji ukazuje na prvi vor ispred na naj- kraem putu od do , pomou koga rekonstrui- šemo najkrai put
Primer
Primer
Primer
Primer
Evo plana kako da izraunamo najkrae puteve:
Kreemo od startnog vora i stalno uveavamo region grafa u kome su rastojanja i najkrai putevi poznati.
To uveanje mora da bude prema odreenom redosledu – prvo ukljuujemo najblie vorove, a onda prelazimo na one koji su malo dalje.
Preciznije, kada je „poznati region“ neki podskup skupa vorova koji uklju-uje , onda naredni dodati vor mora biti onaj vor van koji je najblii do ; neka to bude vor ;
Kako ga identifikovati?
Neka je vor neposredno ispred na najkraem putu od do
pošto su duine grana pozitivne, mora biti blie do od
Što znai da je u , u suprotnom bi to bilo u kontradikciji sa izborom kao vora iz najblieg do vora .
Alternativno izvoenje
Prema tome, najkrai put od do je poznati najkrai put proširen jednom granom (single-edge proširenje)
Moe da postoji više single-edge proširenja trenutno poznatih najkraih puteva; koji od njih identifikuje ?
odgovor je: najkrai od tih single-edge proširenih puteva! (poslednji vor najkraeg proširenog puta je vor van najblii do , pa to mora biti baš )
Alternativno izvoenje
Sada je lako pronai – to je vor van kod koga je postignuta najmanja vrednost + (, ), gde prolazi kroz skup .
Treba proveriti sva single-edge proširenja trenutno poznatih najkraih puteva, nai najkrae, i njegov završni vor e biti sledei koji dodajemo u
D
odatna efikasnost potie iz injenice da u svakoj novoj iteraciji, jedina nova proširenja su ona koja ukljuuju poslednji vor koji smo dodali u , jer su sva ostala proširenja prethodno razmatrana i nema potrebe ponovo ih raunati
Vreme realizacije
Dijkstrin algoritam je strukturno slian BFS-u, ali je sporiji, jer je kju prioriteta zahtevniji od obinog kjua.
Kako makequeue traje kao || insert operacija, to dobijamo ukupno || deletemin i + || insert/decreasekey operacija
Pri tome, vreme potrebno za realizaciju ovih operacija zavisi od toga za koju implementaciju kjua prioriteta smo se odluili:
Pohlepni algoritmi
Pohlepni algoritmi predstavljaju algoritamsku strategiju kod koje se problem rešava deo po deo, pri emu se uvek bira naredni deo koji nudi najoigledniju neposrednu korist.
Ovakva strategija u mnogim sluajevima ne daje dobre rezultate:
Na primer, u šahu ne bi dala rezultate, jer moramo dobro isplanirati više poteza unapred i planiranje samo narednog poteza vrlo brzo dovodi do poraza.
Meutim, postoje i sluajevi gde ovakva pohlepna strategija daje rezultate i razmotriemo takve sluajeve.
Minimalna razapinjua stabla
Pretpostavimo da nam je dat zadatak da umreimo kolekciju raunara pove- zujui izabrane parove tih raunara.
Ovaj zadatak moe se prevesti u problem teorije grafova, gde su vorovi rau- nari, neusmerene grane su potencijalne veze izmeu njih, i cilj je da izabere- mo dovoljno tih grana da vorovi budu povezani.
Meutim, to nije sve. Svaka veza takoe ima svoje troškove odravanja, koje predstavljamo kao teine grana (naš graf je neusmeren i teinski).
Pitanje je: Koja je najjeftinija mogua mrea?
Ono što odmah moemo uoiti je da optimalan skup grana ne moe sadrati ciklus, jer uklanjanjem grane sa tog ciklusa moemo redukovati cenu bez da poremetimo povezanost.
Minimalna razapinjua stabla
Svojstvo 1 Uklanjanje grane sa ciklusa ne moe poremetiti povezanost grafa.
Prema tome, rešenje koje traimo mora biti povezan i aciklian graf.
Neusmereni grafovi tog tipa nazivaju se stabla.
Stablo koje mi traimo je ono sa minimalnom ukupnom teinom, i poznato je kao minimalno razapinjue stablo.
Input: Neusmeren graf = (, ); teine grana
Output: Stablo = (, ′), sa ′ ⊆ , i minimalnim
weight =
∈′
U prethodnom primeru, minimalno razapinjue stablo ima cenu (teinu) 16:
Pohlepni pristup
Uzastopno dodavati po jednu najlakšu granu koja ne proizvodi ciklus.
Drugim reima, konstruišemo stablo granu po granu i, pored toga što pazimo da izbegnemo cikluse, jednostavno biramo onu granu koja je najjeftinija u da-tom trenutku.
Jasno, to je pohlepni algoritam: svaka odluka koju donosimo je ona koja u istom trenutku donosi najoigledniju prednost.
Da li je ovo jedino
optimalno rešenje?
Minimalno razapinjue stablo dobijeno Kruskalovim algoritmom:
Najpre poreajmo grane po teinama, od najlakše do najtee, pri emu grane iste teine moemo poreati bilo kojim redosledom:
Krenimo sada sa praznim grafom i dodajmo jednu po jednu granu, po tom redosledu, tako da ne dobnijemo ciklus. Sa prve dve grane nam to uspeva, ali sa treom, granom − , to ne uspeva, jer bi inae dobili ciklus.
U tom sluaju, tu granu ignorišemo i idemo dalje. Konaan rezultat je stablo sa najmanjom moguom cenom 14.
Svojstvo seenja– Cut property
Korektnost Kruskalovog metoda sledi direktno iz tzv. svojstva seenja.
Recimo da smo u procesu izgradnje minimalnog razapunjueg stabla (MST) ve izabrali neke grane i da smo za sada na pravom putu.
Koju granu treba sledeu da dodamo?
Svojstvo seenja: Pretpostavimo da je skup grana deo nekog minimalnog razapinjueg stabla grafa = (, ). Izaberimo bilo koji skup grana tako da ne prelazi izmeu i \, i neka je najlakša grana koja povezuje i \.
Tada je ∪ {} takoe deo nekog minimalnog razapinjueg stabla.
Seenje (cut) je bilo koja particija skupa vorova sa dva bloka, i \.
Svojstvo seenja kae da je uvek bezbedno dodati najlakšu granu preko bilo kog seenja (tj. izmeu jednog vora u i jednog u \), pod uslovom da nema granu preko tog seenja.
Svojstvo seenja– Cut property
Da vidimo zašto to vai. Prema pretpostavci, grane iz su deo nekog MST .
Ako je nova grana takoe deo od , tada nema šta da se dokazuje.
Dakle, uzmimo da nije u . Konstruisaemo drugo MST ′ koje sadri ∪ {} neznatno modifikujui stablo , zamenom samo jedne od njegovih grana.
Dodajmo granu u . Kako je povezano, ve postoji put izmeu krajnjih taa- ka grane , pa se dodavanje grane kreira ciklus.
Taj ciklus mora takoe da ima neku drugu granu ′ preko seenja (, \) (vidi sliku).
Ako sada uklonimo tu granu ′, ostaje nam ′ = ( ∪ )\{′} , za koje emo pokazati da je stablo. Zaista, ′ je povezano na osnovu Svojstva 1, jer je ′ grana na ciklusu.
Takoe, ′ ima isti broj grana kao , pa je ′ takoe stablo.
Svojstvo seenja– Cut property
Osim toga, ′ je minimalno razapinjue stablo. Uporedimo njegovu teinu sa teinom od :
weight ′ = weight + − (′)
I i ′ prelaze izmeu i \, i je po pretpostavci najlakša grana tog tipa.
Prema tome, () ≤ (′) , pa je weight(′) ≤ weight().
Kako jeste MST, onda mora da bude weight ′ = weight() pa ′ takoe jeste MST.
Primer
Sada emo potvrditi korektnost Kruskalovog algoritma.
U svakom trenutku, grane koje su ve izabrane ine parcijalno rešenje, kolekciju povezanih komponenti od kojih svaka ima strukturu stabla.
Sledea grana koja treba da bude dodata povezuje dve od tih komponenti, recimo da su to 1 i 2.
Kako je najlakša grana koja ne proizvodi ciklus, sigurno je da je najlakša grana izmeu 1 i \1, pa, prema tome, zadovoljava svojstvo seenja.
Objasnimo sada detalje implementacije algoritma.
U svakom stadijumu, algoritam bira granu koju e dodati trenutnom parcijalnom rešenju.
Da bi se to uinilo, potrebno je proveriti svaku granu kandidata − da bi videli da li krajnje take i lee u razliitim komponentama, u suprotnom ta grana proizvodi ciklus.
Kada je grana izabrana, odgovarajue komponente treba da se spoje.
Koja struktura podataka podrava takve operacije?
Kruskalov algoritam
Inicijalno, svaki vor je sam za sebe komponenta:
(): kreira jednoelementni skup koji sadri samo .
Mi uvek iznova proveravamo parove vorova da bi videli da li pripadaju istom skupu.
(): kom skupu pripada ?
I kad god dodamo granu, mi spajamo dve komponente:
(, ): spaja skupove koji sadre i .
Kruskal's minimum spanning tree algorithm
Ovo je konana verzija algoritma.
Algoritam koristi || makeset, 2|| find, i − 1 union operacija.
Struktura podataka za disjunktne skupove
Predstavljanje usmerenog stabla od dva skupa {B, E} i {A, C, D, F, G, H}
Jedan od naina da se predstavi skup je usmereno stablo.
vorovi stabla su elementi skupa, aranirani bez nekog posebnog redosleda, i svaki od njih ima roditeljski pokaziva koji nas vodi prema korenu stabla.
Element u korenu je zgodan za predstavnika skupa.
On se razlikuje od ostalih elemenata po tome što mu roditeljski pokaziva predstavlja petlju.
Unija po rangu
Pored roditeljskog pokazivaa , svaki vor takoe ima rang koji se moe interpretirati kao visina podstabla koje izlazi iz tog vora.
Kao što se moe oekivati, makeset je operacija koja troši konstantno vreme.
Sa druge strane, find sledi roditeljski pokaziva do korena stabla, pa, prema tome, zahteva vreme proporcionalno visini stabla.
Stablo se zapravo gradi treom operacijom, union, pa treba da budemo sigurni da procedura ostavlja stablo plitkim.
Unija po rangu
Stapanje (merging) dva skupa je jednostavno: spojimo koren stabla jednog od tih skupova sa korenom stabla drugog skupa.
Meutim, ovde treba da napravimo izbor. Ako predstavnici (koreni) dva skupa jesu i , da li vezujemo za ili obratno?
Kako je za efikasnost algoritma najvanija visina stabla, dobra strategija je da se postavi grana iz korena nieg stabla u koren višeg stabla.
Na taj nain se stapanjem dobija više stablo samo ako su oba stabla koja se stapaju iste visine, pri emu se visina uveava samo za 1.
Umesto da eksplicitno raunamo visinu stabala, mi emo koristiti rang brojeve njihovih korena, zbog ega se i ovaj metod naziva unija po rangu.
Procedura union
Unija po rangu
Oigledno, rang vora je upravo visina podstabla iji koren je taj vor.
To znai, na primer, kako se kreemo naviše prema korenu stabla, vrednosti ranga se du tog puta uveavaju.
Property 1 Za svaki , rank < rank( ).
Property 2 Svaki vor ranga ima najviše 2 vorova u svom podstablu.
Property 3 Ako ukupno ima elemenata, tada moe biti najviše /2 vo- rova ranga .
Iz poslednjeg svojstva sledi da rang moe biti maksimalno log .
Prema tome, sva stabla imaju visinu ≤ log, i to je gornja granica vremena rada za find i union.
Primer – Kruskalov algoritam
Primer – Kruskalov algoritam
Primer – Kruskalov algoritam
Primer – Kruskalov algoritam
Primer – Kruskalov algoritam
Kompresija puteva
Sa strukturom podataka o kojoj smo do sada govorili, ukupno vreme rada Kruskalovog algoritma je (|| ||) za sortiranje grana (imajmo u vidu da je || ≈ ||) plus još jedno (||||) za operacije union i find koje dominiraju u ostatku algoritma.
Dakle, ini se da nema mnogo prostora da se naša struktura podataka uini još
efikasnijom.
Meutim, šta ako su grane ve sortirane? Ili ako su teine male (recimo,
(||)), pa se sortiranje moe izvršiti u linearnom vremenu?
U takvim sluajevima razmatrana struktura podataka postaje usko grlo, i
korisno je razmišljati o tome da njene performanse poboljšaju ispod po
operaciji.
Moemo razmišljati o izvesnoj operaciji odravanja za union-find strukturu,
koja bi odravala stabla kratkim tokom svake find operacije, kada se sledi niz
roditeljskih pokazivaa do korena stabla, gde moemo izmeniti sve te
pokazivae tako da ukazuju direktno na koren stabla.
Primer – kompresija puteva
Takva kompresija puteva (path compression) samo malice uveava vreme potrebno za find operaciju i lako se kodira.
Dobit od ove jednostavne izmene više dolazi do izraaja dugorono nego trenutno, i stoga zahteva posebnu analizu.
Treba posmatrati nizove find i union operacija, koje kreu od prazne struk- ture podataka, i odrediti proseno vreme po operaciji.
U tom sluaju e potrebno vreme po operaciji biti jedva nešto više od (1), što je nie od ranijeg (log ).
Primov algoritam
Vratimo se na našu diskusiju o algoritmima za konstrukciju minimalnog razapinjueg stabla.
Ono što nam svojstvo seenja kae u najopštijim crtama glasi da e svaki algoritam koji prati sledeu pohlepnu strategiju gatarnovano raditi.
Popularna alternativa Kruskalovom algoritmu je Primov algoritam, gde u svakom meukoraku skup grana uvek ini podstablo, a se bira kao skup vorova tih stabala.
Primov algoritam
U svakoj iteraciji, podstablo odreeno sa se uveava za po jednu granu, i to za onu najlakšu izmeu vora iz i vora van (Figure 5.8).
Ekvivalentno, moemo zamisliti da raste tako što ukljuuje vor ∉ sa najmanjom cenom:
Primov algoritam
Primov algoritam jako lii na Dijkstrin algoritam, pseudokodovi su im skoro identini (Figure 5.9).
Jedina razlika je u kljunim vrednostima pomou kojih je kju prioriteta ureen.
Kod Primovog algoritma, vrednost vora je teina najlakše ulazne grane iz skupa , dok je kod Dijkstrinog algoritma to duina celog puta do tog vora iz startnog vora.
U svakom sluaju, dva algoritma su dovoljno slina da imaju isto vreme rada, koje zavisi od konkretne implementacije kjua prioriteta.
Fig. 5.9 pokazuje kako radi Primov algoritam na malom grafu sa 6 vorova.
Primetimo da je završno MST potpuno odreen nizom prev.
Primov algoritam