PROJKTOWNI LGORYTMÓW I MTOY SZTUZNJ INTLIGNJI GRY.. PRZSZUKIWNI W GŁĄ Wykład 1 dr inż. Łukasz Jeleń Na podstawie wykładów dr. T. evensa PRZSZUKIWNI W GŁĄ (S) LGORYTM S jest techniką trawersowania grafów S Odwiedza wszystkie wierzchołki i krawędzie grafu G Sprawdza czy G jest spójny Wyznacza komponenty połączone grafu Wyznacza las rozpinający grafu zas S dla grafu z n wierzchołkami i m krawędziami to O(n + m ) S może być rozszerzony do rozwiązywania innych problemów związanych z grafami Znajdywanie ścieżki między dwoma zadanymi wierzchołkami Znajdywanie cykli w grafie Przeszukiwanie w głąb dla grafu jest równoważne ze ścieżką ulera dla drzew binarnych ziała na zasadzie ustawiania i pobierania etykiet wierzchołków i krawędzi lgorytm S(G) Wejście graf G Wyjście etykiety krawędzi grafu G ustawiane jako znalezione krawędzie i krawędzie powrotne for all u G.vertices() setlabel(u, NIOWIZONY) for all e G.edges() setlabel(e, NIOWIZONY) for all v G.vertices() if getlabel(v) = NIOWIZONY S(G, v) lgorytm S(G, v) Wejście graf G i wierzchołek początkow v grafu G Wyjście etykiety krawędzi grafu G w komponencie połączonym v jako znalezione krawędzie i krawędzie powrotne setlabel(v, VISIT) for all e G.incidentdges(v) if getlabel(e) = NIOWIZONY w opposite(v,e) if getlabel(w) = NIOWIZONY setlabel(e, ZNLZION) S(G, w) else setlabel(e, POWROTNY) PRZYKŁ PRZYKŁ -.. nieodwiedzony wierzchołek odwiedzony wierzchołek nieodwiedzona krawędź odnaleziona krawędź krawędź powrotna
WŁŚIWOŚI S SZUKNI ŚIŻKI Właściwość 1 S(G, v) odwiedza wszystkie wierzchołki i krawędzie w komponencie połączonym wierzchołka v Właściwość Odnalezione przez S(G, v) krawędzie tworzą drzewo rozpinające komponentu połączonego wierzchołka v Możemy zmodyfikować algorytm S tak, aby znajdował ścieżkę między dwoma wierzchołkami u i z z zastosowaniem metody szablonowej Wywołujemy S(G, u) z u jako wierzchołek startowy Wykorzystujemy stos S do śledzenia ścieżki między wierzchołkiem startowym, a bieżącym W momencie osiągnięcia wierzchołka końcowego z zwracamy ścieżkę jako zawartość stosu lgorytm paths(g, v, z) setlabel(v, OWIZONY) S.push(v) if v = z return S.elements() for all e G.incidentdges(v) if getlabel(e) = NIZNLZION w opposite(v,e) if getlabel(w) = NIZNLZION setlabel(e, ZNLZION) S.push(e) paths(g, w, z) S.pop(e) else setlabel(e, POWROTNY) S.pop(v) PRZSZUKIWNI WSZRZ (S) PRZSZUKIWNI WSZRZ S jest również techniką trawersowania grafu S Odwiedza wszystkie wierzchołki i krawędzie Sprawdza czy G jest spójny Wyznacza komponenty połączone grafu Wyznacza las rozpinający grafu zas S dla grafu z n wierzchołkami i m krawędziami to O(n + m ) S może być rozszerzony do rozwiązywania innych problemów związanych z grafami Znajdywanie ścieżki o minimalnej ilości krawędzi między dwoma wierzchołkami Znajdywanie prostych cykli, jeśli takie istnieją 10 LGORYTM PRZYKŁ ziała na zasadzie ustawiania i pobierania etykiet wierzchołków i krawędzi lgorytm S(G) Wejście graf G Wyjście etykiety krawędzi i podział wierzchołków grafu G for all u G.vertices() setlabel(u, NIOWIZONY) for all e G.edges() setlabel(e, NIOWIZONY) for all v G.vertices() if getlabel(v) = NIOWIZONY S(G, v) lgorytm S(G, s) pusta kolejka.insertlast(s) setlabel(s, OWIZONY) i 0 while ~L i.ismpty() L i +1 pusta kolejka for all v L i.elements() for all e G.incidentdges(v) if getlabel(e) = NIOWIZONY w opposite(v,e) if getlabel(w) = NIOWIZONY setlabel(e, ONLZIONY) setlabel(w, OWIZONY) L i +1.insertLast(w) else setlabel(e, POPRZZNY) i i +1 nieodwiedzony wierzchołek odwiedzony wierzchołek nieodwiedzony krawędź odnaleziona krawędź krawędź poprzeczna 11 1
PRZYKŁ -.. PRZYKŁ -.. 1 1 WŁŚIWOŚI Oznaczenie G s : komponent połączony węzła s Właściwość 1 S(G, s) odwiedza wszystkie wierzchołki i krawędzie grafu G s Właściwość Znalezione krawędzie oznaczone przez S(G, s) tworzą drzewo rozpinające T s dla G s Właściwość la każdego wierzchołka v w L i Ścieżka T s od s do v posiada i krawędzi Każda ścieżka z s do v w G s posiada przynajmniej i krawędzi GRY SKIROWN OS OR JK SO W LX MI 1 1 IGR WŁŚIWOŚI igraph jest grafem, którego wszystkie krawędzie są skierowane Skrót od directed graph Zastosowanie ulice jednokierunkowe loty szeregowanie/ planowanie zadań Graf G=(V,) taki, że Każda krawędź jest skierowana: Krawędź (a,b) idzie od a do b, ale nie od b do a. Jeśli G jest prosty, to m < n*(n-1). Jeśli będziemy przechowywali krawędzie wejściowe i wyjściowe w osobnych listach sąsiedztwa, to możemy wymienić/wypisać te krawędzie czasie proporcjonalnym do rozmiaru list. 1 1
ZSTOSOWNI IGRU Planowanie: krawędź (a,b) oznacza, że zadanie a musi zostać zakończone przed rozpoczęciem zadania b ics1 ics ics S L IGRU Możemy zmodyfikować algorytmy trawersowania (S i S) dla digrafu w taki sposób aby trawersowały krawędzie tylko zgodnie z ich kierunkiem ics1 ics11 ics11 ics ics11 ics ics11 ics11 ics11 obra jakość życia W digrafach algorytm S będzie zawierał rodzaje krawędzi: krawędzie odnalezione krawędzie powrotne (wskazuje na poprzednika) krawędzie następujące (wskazuje na następcę) krawędzie poprzeczne (wskazuje na każdy inny wierzchołek) S dla digrafu rozpoczynając w wierzchołku s wyznacza wierzchołki osiągalne z s 1 0 S L IGRU PROGRMOWNI YNMIZN W digrafach algorytm S będzie zawierał rodzaje krawędzi: krawędzie odnalezione krawędzie powrotne (wskazuje na poprzednika) krawędzie poprzeczne (wskazuje na każdy inny wierzchołek) S dla digrafu rozpoczynając w wierzchołku s także wyznacza wierzchołki osiągalne z s 1 IĄG IONIGO iąg ibonacciego: 0, 1, 1,,,,, 1, 1, i = i jeśli i 1 i = i-1 + i- jeśli i Rozwiązanie w sposób rekurencyjny: Wiele powtarzanych obliczeń Powinien być rozwiązany z pomocą jednej pętli PROGRMOWNI YNMIZN Metoda projektowania algorytmów wykorzystywana w sytuacjach kiedy dany problem może zostać przedstawiony jako sekwencja decyzji rozwiązanie problemu nie jest traktowane jako pojedynczy problem wiele podproblemów muszą być niezależne od siebie rozpoczynamy od najprostszych matematyczna technika wyznaczania rozwiązań optymalnych
IĄG IONIGO Wyznaczanie n-tego wyrazu wersja rekurencyjna zas: O( n ) unsigned long fib(int n) { if(n <= 1) return n; else return fib(n - ) + fib(n - 1); iąg wywołań rekurencyjnych fib()=fib(1)+fib()=fib(1)+fib(0)+fib(1) =1+0+1= IĄG IONIGO Wyznaczanie n-tego wyrazu z zastosowaniem programowania dynamicznego int fibonacci(int n) { int a, b; if(n == 0) return 0; a = 0; b = 1; for(int i=0; i<(n-1); i++) { b += a; a = b-a; return b; zas: O(n) PRZYKŁ - OLIZNI SYMOLU NWTON wersja rekurencyjna nieoptymalne - prowadzi do czasu wykładniczego i może powodować wywoływanie wykładniczą ilość rekurencji PRZYKŁ - OLIZNI SYMOLU NWTON programowanie dynamiczne mała liczba podproblemów -> O(n ) wersja iteracyjna for ( int i = 1; i<= n; i++) tab[i][0] = 1;... function symbol(int n,int k){ for (int j = 1; j<=k; j++) tab[j][j]= 1; for (int i = j + 1; i<=n; i++) tab[i][j] = tab[i 1][j 1] + tab[i 1][j]; return tab[n][k]; KONPJ PROGRMOWNI YNMIZNGO programowanie dynamiczne -> rozwiązywanie problemu "od końca" Kroki: rozwiąż problem dla jednego elementu dla różnych wartości parametru sterującego zapamiętaj wyniki, dodaj kolejny element do problemu zbuduj rozwiązanie problemu powiększonego o nowy składnik wybór dokonywany optymalnie w oparciu o wcześniejsze rozwiązania (zpisane) ZS OPTYMLIZJI Załóżmy, że podczas rozwiązywania problemu mamy dokonać decyzji 1,,, n. Jeśli sekwencja ta jest optymalna to ostatnie k decyzji, 1<k<n musi być optymalne np.: problem znajdywania najkrótszej ścieżki Jeśli i, i1,i,, j jest najkrótszą ścieżką od i do j, to i1, i,, j musi być najkrótszą ścieżką od i1 do j Jeśli problem może być opisany przez wielopoziomowy graf, to może zostać rozwiązany z zastosowaniem programowania dynamicznego 0
PROGRMOWNI YNMIZN wa podejścia: Postępujące (orward) jeśli problem jest zdefiniowany postępująco, to relacje są rozwiązywane wstecznie rozpoczynając od ostatniej decyzji wsteczne (ackward) analogicznie, jeśli relacje są formułowane wstecznie, to będą rozwiązywane postępująco o rozwiązania problemu z zastosowaniem programowania dynamicznego musimy: Znaleźć relacje rekurencyjne Przedstawić problem w postaci grafu wielopoziomowego 1 PROLM LOKJI ZSOÓW mamy m zasobów i n projektów zysk z(i, j): j zasobów zostało przydzielonych do projektu i maksymalizujemy zysk całkowity Resource Project 1 1 ROZWIĄZNI GROW Graf wielopoziomowy S I 0,1 0 0, 0 0, 0 J 1,1 0 1, 0 1, G K,1 0, 0, 0 H L,1 0, 0, Problem alokacji zasobów może być przedstawiony w formie grafu wielopoziomowego (i, j): i zasobów przydzielonych do projektów 1,,, j n.p.: węzeł H = (, ): zasoby przydzielone do projektów 1, T PROLM KOMIWOJŻR Komiwojażer chce odwiedzić dany zbiór miast i powrócić do początku przemierzając najmniejszy możliwy dystans Problem łatwy do opisania ale trudny do rozwiązania PROLM KOMIWOJŻR Nawet jeżeli nie mamy wymogu powrotu do początku, to i tak problem może być traktowany jako PK PROLM KOMIWOJŻR Załóżmy, że chcemy przejechać z miasta do odwiedzając wszystkie miasta wirtualny wierzchołek o odległości = 0
PROLM KOMIWOJŻR ROZWIĄZNI GROW Inny przykład igraf Macierz kosztów 1 10 1 1 10 Może opisać wszystkie możliwe przejścia digrafu Najkrótsza ścieżka: (1,,,, 1) +++=1 (1,) 10 (1) (1,) (1,) Û (1,,) (1,,) (1,,) (1,,) (1,,) (1,,) Û (1,,,) (1,,,) (1,,,) (1,,,) (1,,,) (1,,,) 1 RPRZNTJ WIRZHOŁK PROGRMOWNI YNMIZN Załóżmy, że w grafie mamy wierzchołków. Możemy połączyć {1,,, i {1,,, w jeden wierzchołek. (1,,) (1,,,) (1,,) (1,,,) (a) combine (), (,,) (), (,,) (),(,, ) oznacza, że ostatni odwiedzony wierzchołek to, a pozostałe wierzchołki do odwiedzenia to (,, ) (b) (), (,) Niech g(i, S) będzie długością najkrótszej ścieżki począwszy od wierzchołka i, przechodzącą przez wszystkie wierzchołki S i skończywszy w wierzchołku 1. ługość optymalnej podróży: W formie ogólnej: Złożoność czasowa: g(1, V -{1) = {c1k + g(k, V -{1, k) min k n g(i, S) n + = j S min{c + g(j, S-{j) ij n n ( n 1)( n k )( n k) ( ),( ) (n-k) k = (n-1) n ( n ) = O(n ) n k 0