LAB: Przeszukiwanie grafów i planowanie tras przejazdu

Celem ćwiczenia jest zapoznanie się z możliwościami wykorzystania Prologu do planowania tras przejazdu oraz poznanie technik poszukiwania ścieżek w grafach i ich implementacji w Prologu.

1 Wprowadzenie

Modelem przestrzeni poszukiwań dla planowania tras przejazdu jest graf.

Graf to twór matematyczny składający się ze zbioru wierzchołków V (ang. nodes, vertices) oraz zbioru krawędzi E (ang. links, edges).

Najprostsza definicja grafu mówi, że graf to para postaci G=(V,E), gdzie V jest zbiorem węzłów a E ⊆ V×V jest zbiorem łączących je krawędzi.

Model ten reprezentuje schematycznie mapę, gdzie w zależności od poziomu abstrakcji węzły mogą np. reprezentować miasta, a krawędzie - łączące je drogi, lub też węzły mogą reprezentować skrzyżowania ulic a krawędzie ulice (lub ich odcinki).

Zapoznaj się, lub raczej przypomnij sobie ;-) podstawowe wiadomości o grafach.

Pamiętaj, że krawędź grafu może być skierowana (modeluje przejazd tylko w jedną stronę; np. ulica jednokierunkowa) lub nieskierowanym (modeluje przejazd w obie strony; np. ulica dwukierunkowa).

Odpowiednio, graf może być grafem skierowanym, nieskierowanym lub mieszanym.

Ponadto, z każdą krawędzią może być związany koszt przejazdu (odległość, czas).

Jeżeli dwa węzły grafu połączone są więcej niż jedną krawędzią, krawędzie te muszą być etykietowane dla umożliwienia ich rozróżnienia.


2 Poszukiwanie ścieżek

Zadanie planowania tras przejazdu to zadanie polegające na wyznaczeniu drogi łączącej zadany punkt początkowy i pożądany punk docelowy.

Zwykle dążymy do wyznaczenia trasy najkrótszej, najszybszej lub o najniższym koszcie.

Modelem zadania planowania trasy jest poszukiwanie ścieżki w grafie.

Zadania planowania trasy definiowane jest jako:

P = (v_I, v_G, V, E)

gdzie v_I to zadany węzeł początkowy, v_G to zadany węzeł docelowy, a V oraz E definiują graf (przestrzeń poszukiwań).

Rozwiązaniem zadania planowania trasy jest ciąg krawędzi e_1, e_2,…,e_n, taki, że:

  • {e_1, e_2,…,e_n} ⊆ E,
  • e_1 zaczyna się węźle v_I,
  • krawędź e_i kończy się w węźle będącym początkiem krawędzi e_i+1,
  • krawędź e_n kończy się w węźle v_G.

Powyższy ciąg krawędzi tworzy ścieżkę stanowiącą plan przejazdu.

Zwykle wymaga się aby każdy węzeł leżący na ścieżce przejazdu odwiedzany był tylko raz (brak cykli).

Znanych jest wiele algorytmów przeszukiwania grafów, zarówno w obszarze teorii grafów, badań operacyjnych jak i sztucznej inteligencji.

Algorytmy z obszaru sztucznej inteligencji wyróżniają się tym, że:

  • często korzystają z heurystyk odległościowych (np. opartych na oszacowaniu odległości Euklidesowej i wg metryki ulicznej),
  • pozwalają na uwzględnianie dodatkowych ograniczeń, np. węzłów zabronionych,
  • pozwalają na przeszukiwanie przestrzeni o bardzo dużych rozmiarach,
  • pozwalają na przeszukiwanie przestrzeni zadanych niejawnie (nowe węzły lub stany pojawiają się w wyniku wywołania funkcji generującej).

Zapoznaj się z podstawowymi algorytmami:

Plan dopuszczalny to plan stanowiący rozwiązanie (ścieżka łącząca węzeł początkowy i docelowy) i ew. spełniający zadane ograniczenia (np. długości, omijania wybranych węzłów zabronionych, przechodzenia przez zadane węzły wymagające odwiedzenia, etc. Plan ten nie musi być 'najlepszy'.

Plan optymalny to plan najlepszy w sensie wybranego kryterium, np.

  • plan zawierający najmniejszą liczbę węzłów,
  • plan realizujący najkrótszą trasę,
  • plan o najtańszej trasie przejazdu,
  • plan pozwalający na najszybszy przejazd.

3 Szukanie w AI

Więcej o metodach szukania w AI można znaleźć w podręczniku

4 Obsługa list w Prologu

Na zajęciach wykorzystujemy wbudowane predykaty do obsługi list. Zobacz dokumentację SWI: A.12 library(lists): List Manipulation

Możesz też zawsze przeczytać pomoc, np. help(append).


5 Grafy i ich reprezentacja w Prologu

W Prologu można reprezentować grafy na kilka sposobów.

Najprostszą i efektywną metodą jest zadeklarowanie połączeń pomiędzy węzłami grafu w postaci faktów w Prologu.

Rozważmy następujący graf:

Przykład grafu - model połączeń drogowych

Przykład grafu - model połączeń drogowych (.pdf)

W grafie tym istnieje jedna ścieżka optymalna (lewa krawędź) oraz wiele ścieżek dopuszczalnych przechodzących przez węzły n1-n6.

Reprezentacja tego grafu w Prologu ma postać:

d(s,g).
d(s,n1).
d(s,n2).
d(n1,n2).
d(n1,n4).
d(n1,n3).
d(n2,n3).
d(n3,n4).
d(n3,n5).
d(n4,n5).
d(n4,n6).
d(n5,n6).
d(n6,g).

Jak widać, każda krawędź zapisywana jest w postaci relacji d(<węzeł_początkowy>,<węzeł_końcowy>).

W przykładowym grafie istnieje 13 krawędzi. Zgodnie z deklaracją w Prologu, są to krawędzie skierowane (dlaczego?)

Aby zadeklarować możliwość przejazdu w obie strony, należy zdefiniować domknięcie symetryczne relacji połączenie d/2.

%%% domknięcie symetryczne relacji d/2 
     przejazd(X,Y):- d(X,Y).
     przejazd(X,Y):- d(Y,X).

Tak więc, każda krawędź umożliwia przejazd w obie strony.

Zadania

  1. Przerysuj pokazany graf na kartce papieru.
  2. Znajdź - wspomagając się rysunkiem kilka możliwych alternatywnych tras przejazdu; zaznacz je na rysunku.
  3. Spróbuj wyznaczyć wszystkie różne trasy przejazdu (nie zawierające cykli); ile ich jest?

6 Poszukiwanie tras przejazdu

Rozważmy najprostszy program realizujący zadanie poszukiwania tras przejazdu:

%%% domknięcie tranzytywne relacji przejazd
     szukaj_trasy(Cel,Cel,Trasa,Trasa):- !.
     szukaj_trasy(Miasto,Cel,Robocza,Trasa):- 
         przejazd(Miasto,NoweMiasto),
         not(member(NoweMiasto,Robocza)),
         szukaj_trasy(NoweMiasto,Cel,[NoweMiasto|Robocza],Trasa).

Predykat szukaj_trasy/4 ma 4 parametry:

  • aktualny węzeł (Miasto),
  • węzeł docelowy (Cel),
  • cząstkową trasę aktualną (Robocza),
  • trasę docelową (Trasa).

Pierwszy wariant definiuje zakończenie poszukiwań: gdy znajdziemy się w węźle docelowym, trasa Robocza staje się docelową.

Drugi wariant definiuje sposób szukania trasy:

  • będąc w węźle Miasto, znajdź NoweMiasto do którego jest bezpośrednie połączenie (uzywając predykatu przejazd/2,
  • sprawdź, czy nie było już odwiedzane ( not(member(NoweMiasto,Robocza)) ),
  • jeżeli tak, zostanie wymuszony nawrót; jeżeli nie, próbuj dalej i w tym celu
  • zaktualizuj trasę roboczą dokładając NoweMiasto i kontynuuj szukanie z tego miejsca.

Zauważ, że:

  • trasy reprezentowane są jako listy,
  • konstruowana ścieżka wydłuża się w miarę szukania; dokładane są nowe miasta,
  • konstruowane są wszystkie warianty planu - dzięki mechanizmowi nawrotów w Prologu,
  • żaden plan nie będzie zawierał cykli.

Zadania

  1. Uruchom podany program dla przykładowego grafu; jak zainicjować parametry?
  2. Zadaj w jakiej kolejności występują miasta na znalezionych trasach. Dlaczego?
  3. Wygeneruj przykładowy plan rozwiązania,
  4. Wygeneruj wszystkie możliwe plany i policz je.

7 Inicjowanie programu i zliczanie rozwiązań

Aby ułatwić uruchamianie programu wyposażymy go w klauzulę inicjującą:

%%% inicjacja szukania
     plan(Start,Cel,Trasa):-
          szukaj_trasy(Cel,Start,[Cel],Trasa).                           

Zauważ, że Start i Cel zamieniły się miejscami. Dlaczego?

Aby wyznaczyć automatycznie wszystkie plany uzupełnimy program o klauzulę:

%%% Find all plans from 's' to 'g'.
     fap(Plans) :- findall(Trasa, plan(s,g,Trasa),Plans).

Aby wyznaczyć automatycznie wszystkie plany i zapisać je do pamięci uzupełnimy program o klauzulę:

%%% Find all plans and assert; p(<plan>).
     fap-assert:- plan(s,g,Plan), assert(p(Plan)), fail.
     fap-assert.

Jaka to konstrukcja? Na czym polega jej działanie?

Pełny program znajdziesz tutaj: plan-robust-count.pl

Zdania

  1. Przeanalizuj elementy i działanie programu.
  2. Jaka jest kolejność węzłów w wygenerowanych planach?
  3. W jakiej kolejności (w jakim kierunku) odbywa się rzeczywista generacja planów?
  4. Policz ile jest planów dopuszczalnych (programowo) i porównaj wynik z rozwiązaniem ręcznym.
  5. Zmodyfikuj program tak, aby dla każdego planu wyznaczał jego długość (ilość odwiedzanych węzłów).
  6. Zastanów się jak zrealizować (a może nawet spróbuj) analogiczny program w Twoim ulubionym języku programowania (np. Java, C++, Python). Porównaj nakład pracy z kodowaniem w Prologu.

8 Szukanie tras przejazdu pomiędzy miastami w Polsce

Załączony program pozwala poszukiwać tras przejazdy pomiędzy wybranymi miastami w Polsce.

Prosty program planowania tras przejazdu: plan.pl

Przeanalizuj działanie programu.

Rozbuduj jego bazę wiedzy - dodaj nowe miasta.

Wypróbuj działanie.

Zadania

  1. Zmodyfikuj program tak, aby generowane plany omijały wybrane (zadeklarowane) miasta zabronione,
  2. Zmodyfikuj program tak, aby generowane plany uwzględniały przejazd przez wybrane (zadeklarowane) miasta konieczne do odwiedzenia,
  3. Zmodyfikuj program tak, aby generowane były jedynie plany o ograniczonej długości (liczba odwiedzanych miast.

9 Szukanie DFS z wyznaczeniem głębokości

Następujący program pozwala wyszukiwać trasy metodą wgłąb (go) i wgłąb z wyliczaniem głębokości.

depth-first-plan.pl

10 Wyznaczanie długości trasy

Następujący program pozwala wyznaczać długość znalezionych tras.

plan_d.pl

Zadania

  1. Uruchom program i przeanalizuj jego działanie.
  2. Modyfikując ograniczenie znajdź wybrane trasy optymalne dla zadanego miasta początkowego i docelowego.
  3. Zmodyfikuj program tak aby automatycznie modyfikował ograniczenie i znajdował trasę optymalną.

11 Znajdowanie trasy optymalnej

Następujący program pozwala automatycznie wyznaczać długość znalezionych tras oraz trasę optymalną (branch and bound).

Wyznaczanie trasy optymalnej: plan_d_opt.pl

Przeanalizuj program i jego działanie.

Czy zaproponowana metoda jest efektywna? Na czym polegają jej niedoskonałości i ograniczenia?


12 Znajdowanie trasy optymalnej z wykorzystaniem nawrotów

Następujący program pozwala wyznaczać długość znalezionych tras oraz znajduje trasę optymalna z wykorzystaniem mechanizmu nawrotów w Prologu.

Planowanie trasy optymalne z nawrotami: plan_f.pl

Zadania

  1. Przeanalizuj szczegółowo działanie programu; wyświetlaj znalezione trasy.
  2. Porównaj efektywność tego programu z poprzednim na wybranych przykładach (użyj meta predykatu time/1).

13 Przeszukiwanie wszerz

Następujący program pozwala wyznaczać plan metodą wszerz (BFS)

breadth-first-plan.pl

Zadania

  1. Przeanalizuj szczegółowo działanie programu; wyświetlaj znalezione trasy.
  2. Porównaj efektywność tego programu z poprzednim na wybranych przykładach (użyj meta predykatu time/1).

14 Szukanie heurystyczne tras

Przeanalizuj działanie programu. Heurystyka jest zadana w szukaj_trasy. Porównaj z wcześniejszymi alg. szukania.

traser.pl

15 Szukanie heurystyczne A* dla 8puzzle

Program bratko-fig12_3f.pl implementuje algorytm A*. Zobacz też: http://artint.info/html/ArtInt_56.html

Sam program wymaga podania opisu problemu przez predykat s(N,M,C).:

  • N bieżący stan w przestrzeni stanów
  • M następny stan
  • C koszt N→M

Wymagane jest też podanie heurystyki h(N,H) - gdzie H to heurystyczna estymacja kosztu najlepszej trasy z N do celu.

Poczytaj o 8-puzzle. W opisie tego problemu używamy innej miary odległości niż np. na drodze, tzw. odległości taksówkarskiej Manhattan_distance

Program bratko-fig12_6.pl implementuje opis tego problemu do rozwiązania przez w.w. algorytm A*.

Przykładowe wywołanie:

?- start1( Pos), bestfirst( Pos, Sol), showsol( Sol).

Zobacz rozwiązania dla inne stanów startowych.

  1. dodaj inne stany startowe
  2. dodaj liczenie kroków.
  3. jakie mogą być inne heurystyki?
  4. jak użyć tego programu do tras na mapie (miasta)? czy potrafisz opisać/przenieść problem z wcześniejszych zadań (mapa miast w Polsce).

16 Szukanie -- wizualizacja

Spróbuj zrealizować wizualizację grafu dla tras przez program Graphviz. Vide: programy w metaprogramowanie_i_potoki

17 Szukanie -- synteza

Przeczytaj lab classicsearch. Spróbuj użyć programu AIspace: search najprościej wersji JAR.


If u want 2 know more vel zadanie domowe

pl/prolog/prolog_lab/prolog_lab_graphsearch.txt · ostatnio zmienione: 2019/06/27 15:50 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0