Depth First Search Backtracking Mélységi keresés Depth First Search Backtracking Get ahold of a network, and use the same network to illustrate the shortest path problem for communication newtorks, the max flow problem, the minimum cost flow problem, and the multicommodity flow problem. This will be a very efficient way of introducing the four problems. (Perhaps under 10 minutes of class time.)
Mélységi keresés-backtracking Alapelv: Tetszés szerinti csúcstól (i) elindulva egy úton addig megyünk „mélyre”, ameddig lehet: vagy nincsen további szomszédos csúcs, vagy már jártunk ott. Ha így megakadunk, akkor visszalépünk (backtrack) az előző csúcshoz (pred (i), ha onnan tudunk továbbmenni, akkor megint elindulunk, és addig megyünk…, ha nem, akkor visszalépünk…)
Mélységi keresés-elvi algoritmus (rekurzió) Procedure DFS (ÖF G: v1, …vn csúcsokkal) F: fa, kezdőértéke v1 visit(v1) Procedure visit(i: a G egy csúcsa) FOR j G minden i-vel szomszédos csúcsára, ami még nincsen F-ben F= j csúcs U {ij} él visit(j) END FOR Az algoritmust adatszerkezetekkel kell megvalósítani. Sokféle megvalósítás lehetséges-ld. programozás, nem e tárgy feladata. Az alábbiban F-et az order(csúcs) alapján lehet felépíteni, ez a tömb tartalmazza a csúcsok azonosítóinak sorrendjét.
Mélységi keresés-elvi algoritmus (rekurzióval) Procedure DFS (ÖF G: v1, …vn csúcsokkal) F: fa, kezdőértéke v1 visit(v1) Procedure visit(i: a G egy csúcsa) FOR j G minden i-vel szomszédos csúcsára, ami még nincsen F-ben F= j csúcs U {ij} él visit(j) END FOR Az algoritmust adatszerkezetekkel kell megvalósítani. Sokféle megvalósítás lehetséges-ld. programozás, nem e tárgy feladata. Az alábbiban F-et az order(csúcs) alapján lehet felépíteni, ez a tömb tartalmazza a csúcsok azonosítóinak sorrendjét.
Mélységi keresés másképpen Az algoritmus -felépít és lebont egy listát (LIST), aszerint, hogy tovább tudunk-e menni: LIST: ebbe beletesszük a kiválasztott csúcsokat addig, amíg a visszalépéskor az összes szomszédját meg nem látogattuk. Ha egy csúcs ki van választva, a következő csúcs, amit a lista végére fűzünk, ennek szomszédja. Mindig e LISTa végéről választjuk a következő csúcsot. Ha nem tudunk továbbmenni a kiválasztott csúcsból, akkor csúcsot töröljük a LIST végéről. (ez a visszalépés). Ez az elvi algoritmusban „rejtve van”, egy adott csúcsot meg kell vizsgálni, illeszkedik-e, ha nem, akkor nem hívjuk a visit eljárást.. -tárolja a csúcsnak a fa felépítésekor keletkező sorszámát, ezzel címkézzük a csúcsokat: order(csúcs azonosító)-tömb, ennek értéke az első értékadás után nem változik - tárolja a kiválasztott csúcs szülőjét: pred(csúcsazonosító)-tömb, ennek értéke az első értékadás után nem változik, ez csak a fa felépítésében a visszalépéskor kell -felhasznál egy szigorúan monoton 1-gyel növekvő segédváltozót: Next. Ez akkor növekszik csak, ha tudunk szomszédos csúcsba menni.
Algoritmus a mélységi keresésre begin inicializálás // kezdőértékek beállítása while LIST ø do az i csúcsot választjuk a LISTából; if i szomszédos egy j csúccsal, vagyis van (i,j) él then megjelöljük (sárgával) a j csúcsot; pred(j) := i; // megjegyezzük az ősét next := next + 1 ; order(j) := next; // ez lesz a címkéje, ennek alapján építjük fel a fát a j csúcsot a listához fűzzük (append) LIST; //előrelépés end else töröljük i-t a LIST – ából // visszalépés end;
Kezdőértékek beállítása Inicializálás begin minden csúcs jelöletlen a csúcsok halmazában; jelöljük kis a kezdőcsúcsot s; pred(s) = 0; /*ez megállapodás kérdése, ennek nincsen megelőzője, szülője*/ next := 1; order(s) := next; /*ebben a tömbben tároljuk a csúcsok cimkéit: a felépítendő fában ezen sorrend szerint vesszük a csúcsokat a rájuk illeszkedő élekkel együtt*/ LIST = {s} end
Alapbeállítás 1 2 4 5 3 6 9 7 8 1 2 4 5 3 6 9 7 8 1 1 pred(1) = 0 Next := 1 order(Next) = 1 LIST:= {1} Minden csúcs jelöletlen, a startcsúcs legyen az 1. LIST 1 Next 1
A csúcsok LIST-ájáról az utolsót választjuk 1 2 4 5 3 6 9 7 8 1 1 1 A mélységi keresésben , i lesz az utolsó csúcs a LIST-ában LIST 1 Next 1
Ha van szomszédos csúcs, akkor… 2 4 Megjelöljük a j csúcsot (2), és pred(j) := I 2 2 8 1 1 1 5 7 1 9 3 6 Kiválasztjuk az i-re illeszkedő él: (i,j) másik végpontját (2) Next := Next + 1 order(j) := Next j-t a LIST-ához adjuk LIST 1 2 1 2 Next
A LIST-áról az utolsó csúcsot választjuk: 2 4 2 2 2 8 1 1 1 1 5 7 1 9 3 6 Kiválasztjuk a 2 csúcsot LIST 1 2 1 2 Next
Ha van szomszédos csúcs, akkor… 2 4 4 Megjelöljük a j (most 4) csúcsot, és pred(4) := 3 2 2 2 3 8 1 1 1 1 5 7 1 9 3 6 Kiválasztjuk az i-re illeszkedő él: (i,j) másik végpontját:j (4) Next := Next + 1 order(j) := Next j-t a LIST-ához adjuk LIST 1 2 4 2 3 1 Next
a LIST-áról az utolsó csúcsot választjuk 2 4 4 4 2 2 2 2 3 8 1 1 1 1 1 5 7 A LIST-áról az utolsó csúcsot választjuk: 4 9 3 6 LIST 1 2 4 2 3 1 Next
Ha van szomszédos csúcs, akkor… 2 4 4 4 2 2 2 2 3 8 8 4 1 1 1 1 1 5 7 Next := Next + 1 order(j) := Next j-t a LIST-ához adjuk Kiválasztjuk az i-re illeszkedő él: (i,j) másik végpontját:8 Megjelöljük a j (most 8) csúcsot, és pred(8) := 4 9 3 6 LIST 1 2 4 8 1 3 2 4 Next
a LIST-áról az utolsó csúcsot választjuk 2 4 4 4 2 2 2 2 3 8 8 8 4 1 1 1 1 1 5 7 a LIST-áról az utolsó csúcsot választjuk: 8 9 3 6 LIST 1 2 4 8 3 2 1 4 Next
Ha NINCS szomszédos csúcs, akkor… 2 4 4 4 2 2 2 2 3 8 8 8 8 4 1 1 1 1 1 5 7 9 3 6 Az utolsó (i.) csúcsot, most 8, töröljük a listáról (de a fában már benne van, az order(8) nem változik) LIST 1 2 4 8 1 3 2 4 Next
a LIST-áról az utolsó csúcsot választjuk 2 4 4 4 4 2 2 2 2 3 8 8 8 8 4 1 1 1 1 1 5 7 a LIST-áról az utolsó csúcsot választjuk:4 9 3 6 LIST 1 2 4 8 1 4 2 3 Next
Ha van szomszédos csúcs, akkor… 2 4 4 4 4 2 2 2 2 3 8 8 8 8 4 5 1 1 1 1 1 5 5 7 Next := Next + 1 order(j) := Next j-t hozzáadjuk a LIST-ához Kiválasztjuk az i-re illeszkedő él: (i,j) másik végpontját:5 Megjelöljük a j (most 5) csúcsot, és pred(5) := 4 9 3 6 LIST 1 2 4 8 5 5 3 1 2 4 Next
A LIST-áról az utolsó csúcsot választjuk 2 4 4 4 4 4 2 2 2 2 3 8 8 8 8 4 5 1 1 1 1 1 5 5 5 7 a LIST-áról az utolsó csúcsot választjuk 9 3 6 LIST 1 2 4 8 5 1 2 5 3 4 Next
Ha van szomszédos csúcs, akkor… 2 4 4 4 4 4 2 2 2 2 3 8 8 8 8 4 5 1 1 1 1 1 5 5 5 7 Next := Next + 1 order(j) := Next j-t hozzáadjuk a LIST-ához Megjelöljük a j (most 6) csúcsot, és pred(6) := 5 Kiválasztjuk az i-re illeszkedő él: (i,j) másik végpontját:6 9 3 6 6 6 LIST 1 2 4 8 5 6 1 6 3 5 2 4 Next
A LIST-áról az utolsó csúcsot választjuk 2 4 4 4 4 4 2 2 2 2 3 8 8 8 8 4 5 1 1 1 1 1 5 5 5 5 7 A LIST-áról az utolsó csúcsot választjuk: 6 9 3 6 6 6 6 LIST 1 2 4 8 5 6 3 4 6 5 1 2 Next
Ha van szomszédos csúcs, akkor… 2 4 4 4 4 4 2 2 2 2 3 8 8 8 8 4 5 1 1 1 1 1 5 5 5 5 7 Kiválasztjuk az i-re illeszkedő él: (i,j) másik végpontját:9 Next := Next + 1 order(j) := Next j-t hozzáadjuk a LIST-ához Megjelöljük a j (most 9) csúcsot, és pred(9) := 6 9 9 3 6 6 6 7 6 LIST 1 2 4 5 8 6 9 7 3 1 2 4 6 5 Next
A LIST-áról az utolsó csúcsot választjuk 2 4 4 4 4 4 2 2 2 2 3 8 8 8 8 4 5 1 1 1 1 1 5 5 5 5 7 A LIST-áról az utolsó csúcsot választjuk: 9 9 9 9 3 6 6 6 6 7 6 LIST 1 2 4 5 8 6 9 7 1 2 4 6 5 3 Next
Ha van szomszédos csúcs, akkor… 2 4 4 4 4 4 2 2 2 2 3 8 8 8 8 4 5 1 8 1 1 1 1 5 5 5 5 7 7 Next := Next + 1 order(j) := Next j-t hozzáadjuk a LIST-ához Kiválasztjuk az i-re illeszkedő él: (i,j) másik végpontját:7 Megjelöljük a j (most 7) csúcsot, és pred(7) := 9 9 9 9 3 6 6 6 6 7 6 LIST 1 2 4 8 5 6 9 7 1 2 8 4 6 3 5 7 Next
A LIST-áról az utolsó csúcsot választjuk 2 4 4 4 4 4 2 2 2 2 3 8 8 8 8 4 5 1 8 1 1 1 1 5 5 5 5 7 7 7 A LIST-áról az utolsó csúcsot választjuk : 7 9 9 9 9 3 6 6 6 6 7 6 LIST 1 2 4 5 8 6 9 7 4 8 1 6 2 3 5 7 Next
Ha NINCS szomszédos csúcs, akkor… 2 4 4 4 4 4 2 2 2 2 3 8 8 8 8 4 5 1 8 1 1 1 1 5 5 5 5 7 7 7 7 9 9 9 9 3 6 6 6 6 7 6 7 csúcsot (utolsót) töröljük a List-áról LIST 1 2 4 8 5 6 9 7 1 2 8 4 6 3 7 5 next
A LIST-áról az utolsó csúcsot választjuk… 2 4 4 4 4 4 2 2 2 2 3 8 8 8 8 4 5 1 8 1 1 1 1 5 5 5 5 7 7 7 7 9 9 9 9 9 9 9 7 3 6 6 6 6 6 De a 9 csúcs nem szomszédos egyik, még nem látogatott csúccsal sem, Töröljük a listáról a 9 csúcsot: LIST 1 2 4 8 5 6 9 7 4 2 1 3 5 7 6 8 Next
A LIST-áról az utolsó csúcsot választjuk: 6 2 4 4 4 4 4 2 2 2 2 3 8 8 8 8 4 5 1 8 1 1 1 1 5 5 5 5 7 7 7 7 De a 6 csúcsnak nincsen nem látogatott szomszédja 9 9 9 9 9 9 3 6 6 6 6 6 6 7 6 Töröljük a listáról a 6 csúcsot: LIST 1 2 4 5 8 6 9 7 4 3 2 6 7 8 1 5 Next
A LIST-áról az utolsó csúcsot választjuk: 5 2 4 4 4 4 4 2 2 2 2 3 8 8 8 8 4 5 1 8 1 1 1 1 5 5 5 5 5 5 7 7 7 7 De az 5 csúcsnak nincsen nem látogatott szomszédja 9 9 9 9 9 9 3 6 6 6 6 6 6 7 6 Töröljük a listáról az 5 csúcsot: LIST 1 2 4 8 5 6 9 7 3 2 1 4 5 6 8 7 Next
A LIST-áról az utolsó csúcsot választjuk: 4 2 4 4 4 4 4 4 4 2 2 2 2 3 8 8 8 8 4 5 1 8 1 1 1 1 5 5 5 5 5 5 7 7 7 7 De az 4 csúcsnak nincsen nem látogatott szomszédja 9 9 9 9 9 9 3 6 6 6 6 6 6 7 6 Töröljük a listáról az 4 csúcsot: LIST 1 2 4 8 5 6 9 7 7 1 2 5 8 4 6 3 next
A LIST-áról az utolsó csúcsot választjuk: 2 4 4 4 4 4 4 4 2 2 2 2 2 2 3 8 8 8 8 4 5 1 8 1 1 1 1 5 5 5 5 5 5 7 7 7 7 De az 2 csúcsnak nincsen nem látogatott szomszédja 9 9 9 9 9 9 3 6 6 6 6 6 6 7 6 Töröljük a listáról az 2 csúcsot: LIST 1 2 4 5 8 6 9 7 6 3 1 4 5 7 2 8 Next
j-t hozzáadjuk a LIST-ához Megjelöljük a j (most 3) csúcsot, és A LIST-áról az utolsó csúcsot választjuk: 1 Ha van szomszédos csúcs, akkor… 2 4 4 4 4 4 4 4 2 2 2 2 2 2 3 8 8 8 8 4 5 1 8 1 1 1 1 1 5 5 5 5 5 5 7 7 7 7 Next := Next + 1 order(j) := Next j-t hozzáadjuk a LIST-ához Megjelöljük a j (most 3) csúcsot, és pred(3) := 1 Kiválasztjuk az i-re illeszkedő él: (i,j) másik végpontját:3 9 9 9 9 9 9 3 3 6 6 6 6 6 6 7 9 6 LIST 1 3 2 4 8 5 6 9 7 9 1 2 5 8 7 6 4 3 Next
A LIST-áról az utolsó csúcsot választjuk: 2 4 4 4 4 4 4 4 2 2 2 2 2 2 3 8 8 8 8 4 5 1 8 1 1 1 1 1 1 5 5 5 5 5 5 7 7 7 7 De az 3 csúcsnak nincsen nem látogatott szomszédja 9 9 9 9 9 9 3 3 3 3 6 6 6 6 6 6 7 9 6 Töröljük a listáról az 3 csúcsot: LIST 1 2 4 8 5 6 9 7 9 8 5 3 4 2 6 7 1 Next
A LIST-áról az utolsó csúcsot választjuk: 1 2 4 4 4 4 4 4 4 2 2 2 2 2 2 3 8 8 8 8 4 5 1 8 1 1 1 1 1 1 1 1 5 5 5 5 5 5 7 7 7 7 De az 1 csúcsnak nincsen nem látogatott szomszédja 9 9 9 9 9 9 3 3 3 3 6 6 6 6 6 6 7 9 6 Töröljük a listáról az 1 csúcsot: LIST 1 3 2 4 5 8 6 9 7 9 5 2 1 3 4 7 6 8 Next
A LISTa ÜRES! 2 4 4 4 4 4 4 4 2 2 2 2 2 2 3 8 8 8 8 4 5 1 8 1 1 1 1 1 1 1 1 5 5 5 5 5 5 7 7 7 7 9 9 9 9 9 9 3 3 3 3 6 6 6 6 6 6 7 Ez az algoritmus vége 9 6 LIST 1 3 2 4 8 5 6 9 7 8 4 2 7 5 1 6 3 9 next
A Depth-First fa (DFT) 1 3 2 9 8 7 5 4 6 Minden részfa növekvő számozású pontokból áll
Alkalmazások: MI: n – királynő probléma: http://students.ceid.upatras.gr/~papagel/project/kef5_8.htm Tic-tac-toe: http://ostermiller.org/calc/tictactoe.html http://boulter.com/ttt/