• Nie Znaleziono Wyników

1. Algorytmy przeszukiwania. Przeszukiwanie wszerz i w głąb.

N/A
N/A
Protected

Academic year: 2021

Share "1. Algorytmy przeszukiwania. Przeszukiwanie wszerz i w głąb."

Copied!
8
0
0

Pełen tekst

(1)

1. Algorytmy przeszukiwania.

Przeszukiwanie wszerz i w głąb.

Algorytmy przeszukiwania w głąb i wszerz są najczęściej stosowanymi algoryt- mami przeszukiwania. Wykorzystuje się je do zbadania istnienia połączenie między dwoma wierzchołkami w grafie. Aby zbadać istnienie połączenia w grafie podaje- my dwa wierzchołki: pierwszy - zwany stanem początkowym, oraz drugi - zwany stanem końcowym. W przypadku przeszukiwania grafów skończonych omawiane al- gorytmy są równoważne, tzn zbieżność algorytmu przeszukiwania w głąb pociąga za sobą zbieżność algorytmu przeszukiwania wszerz i odwrotnie. Jeżeli przeszukujemy graf nieskończony, algorytm przeszukiwania wszerz jest zbieżny, natomiast algorytm przeszukiwania w głąb nie. Brak zbieżności ma miejsce wówczas, gdy przeszukujemy krawiędź nieskończoną, która nie prowadzi do wierzchołka końcowego.

Omawiając algorytm posłużymi się przykładem. Zadamy konkretny graf oraz stany: początkowy i końcowy i opiszemy przebieg działania algorytmu. Niech dany będzie graf:

Rysunek 1: Graf do przeszukiwania.

Dowolny graf można opisać w postaci listy połączeń. Lista zawiera n linii, gdzie n oznacza liczbę wierzchołków grafu. W i−tej linii są umiszczone numery wierzchoł- ków, z którymi i−ty wierzchołek jest połączony. Lista połączeń dla rozważanego grafu wygląda następująco:

1. 2, 6, 9 2. 1, 3 3. 2, 4 4. 3, 5

(2)

8. 5, 7 9. 1, 10 10. 9, 11 11. 5, 10

Przeszukiwanie wszerz

Przeszukiwanie grafu wszerz polega na odwiedzaniu wszystkich wierzchołków grafu sąsiadujących z wierzchołkiem początkowym, następnie wierzchołków w odle- głośi 2 od wierzchołka początkowego i tak kolejno. Przy każdym odwiedzeniu należy sprawidzić, czy stan, w którym się znajdujemy jest stanem końcowym. Odwiedzając kolejne wierzchołki należy pamiętać, żeby nie odwiedzać wierzchołków wcześniej od- wiedzonych, tzn. każdy wierzchołek możemy odwiedzić dokładnie raz. W przypadku, gdy odwiedzimy wszystkie możliwe wierzchołki i nie znajdziemy stanu końcowego, nie istnieje droga miedzy szukanymi wierzchołkami. Zaletą algorytmu przeszukiwa- nia wszerz jest to, że na pewno nie pominiemy żadnego wierzchołka, zwykle jednak odwiedzamy za dużo wierzchołków, co jest wadą algorytmu.

Przeszukiwanie wszerz odbywa się przy użyciu kolejki FIFO (first in first out).

Algorytm przebiega następująco:

1. Utwórz kolejkę FIFO

2. Zapisz do kolejki stan początkowy 3. Pobierz z kolejki stan i nazwij go S 4. Jesli

(a) S jest poszukiwanym stanem końcowym zwróć SUKCES i zakończ algo- rytm

(b) S=NULL (lista jest pusta) zwróć BRAK ROZWIAZANIA i zakończ al- gorytm

(c) S nie jest poszukiwanym stanem końcowym to generuj wszystkie możliwe stany następujące po S (które można wyprowadzić z S zgodnie z wcześniej ustalonymi regułami a które nie były już rozważane) i zapisz je do kolejki 5. Idz do 3

Zadanie polega na stwierdzeniu, czy w wyżej podanym grafie wierzchołki 1 i 5 są połączone.

Wykorzystywane funkcje:

make fifo() - funkcja tworzy listę typu FIFO put fifo(x) - funkcja dodaje element x do listy get fifo() - funkcja pobiera elemet z listy Oto przebieg wykonywania algorytmu:

(3)

Numer Krok Wykonywana Stan Odwiedzone etapu algorytmu operacja kolejki wierzchołki

1 1 make fifo() NULL NULL

2 2 put fifo(1) 1 1

3 3 S:=get fifo() (S=1) NULL 1

Wykonywanie punktu (c)

4 4 put fifo(2), put fifo(6), 2 6 9 1 2 6 9 put fifo(9)

5 5 Powrót do 3 2 6 9 1 2 6 9

6 3 S:=get fifo() (S=2) 6 9 1 2 6 9

7 4 Wykonywanie punktu (c) 6 9 3 1 2 3 6 9 put fifo(3)

8 5 Powrót do3 6 9 3 1 2 3 6 9

9 3 S:=get fifo() (S=6) 9 3 1 2 3 6 9

10 4 Wykonywanie punktu (c) 9 3 7 1 2 3 6 7 9 put fifo(7)

11 5 Powrót do 3 9 3 7 1 2 3 6 7 9

12 3 S:=get fifo() (S=9) 3 7 1 2 3 6 7 9

13 4 Wykonywanie punktu (c) 3 7 10 1 2 3 6 7 9 10 put fifo(10)

14 5 Powrót do 3 3 7 10 1 2 3 6 7 9 10

15 3 S:=get fifo() (S=3) 7 10 1 2 3 6 7 9 10 16 4 Wykonywanie punktu (c) 7 10 4 1 2 3 4 6 7 9 10

put fifo(4)

17 5 Powrót do 3 7 10 4 1 2 3 4 6 7 9 10

18 3 S:=get fifo() (S=7) 10 4 1 2 3 4 6 7 9 10 19 4 Wykonywanie punktu (c) 10 4 8 1 2 3 4 6 7 8 9 10

put fifo(8)

20 5 Powrót do 3 10 4 8 1 2 3 4 6 7 8 9 10

21 3 S:=get fifo() (S=10) 4 8 1 2 3 4 6 7 8 9 10 22 4 Wykonywanie punktu (c) 4 8 11 1 2 3 4 6 7 8 9 10 11

put fifo(11)

23 5 Powrót do 3 4 8 11 1 2 3 4 6 7 8 9 10 11

24 3 S:=get fifo() (S=4) 8 11 1 2 3 4 6 7 8 9 10 11 25 4 Wykonywanie punktu (c) 8 11 5 1 2 3 4 5 6 7 8 9 10 11

put fifo(5)

26 5 Powrót do 3 8 11 5 1 2 3 4 5 6 7 8 9 10 11

27 3 S:=get fifo() (S=8) 11 5 1 2 3 4 5 6 7 8 9 10 11 28 4 Wykonywanie punktu (c) 11 5 1 2 3 4 5 6 7 8 9 10 11

nic

29 5 Powrót do 3 11 5 1 2 3 4 5 6 7 8 9 10 11

30 3 S:=get fifo() (S=11) 5 1 2 3 4 5 6 7 8 9 10 11 31 4 Wykonywanie punktu (c) 5 1 2 3 4 5 6 7 8 9 10 11

nic

32 5 Powrót do 3 5 1 2 3 4 5 6 7 8 9 10 11

33 3 S:=get fifo() (S=5) NULL 1 2 3 4 5 6 7 8 9 10 11

(4)

Przeszukiwanie grafu w głąb polega na przeszukiwaniu poszczególnych krawędzi grafu. Przechodzimy krawędz najdalej ja się da, jeżeli dana ścieżka nie doprowadziła nas do wierzchołka końcowego wówczas cofamy sie do momentu, z którego możemy pójść inną scieżką. Podobnie jak w przypadku przeszukiwania wszerz, przeszukując graf metodą w głąb pojedynczy wierzchołek może być odwiedziny dokładnie jeden raz. Przy każdym odwiedzeniu należy sprawidzić, czy nie znajdujemy się w sta- nie końcowym. W przypadku, gdy odwiedzimy wszystkie możliwe wierzchołki i nie znajdziemy stanu końcowego, nie istnieje droga miedzy szukanymi wierzchołkami.

Zaletą algorytmu przeszukiwania w głąb jest to, że nie przeszukujemy wszystkich wierzchołków grafu, dodatkowo przeszukując ścieżką prowadzącą bezpośrednio do wierzchołka końcowego możemy odwiedzić minimalną ilość wierzchołków łączących stan początkowy z końcowym. Wadą jest to, że zwykle przszukiwanie odbywa się niewłaściwą scieżką co prowadzi do zabrnięcia w ”ślepą uliczkę”, z której należy się wycofać do wierzchołka, z którego istnieje możliwość pójścia dalej.

Przeszukiwanie w głąb odbywa się przy użyciu kolejki LIFO (last in first out) zwanej inaczej STOS. Algorytm przebiega następująco:

1. Utwórz STOS

2. Zapisz na stos stan początkowy 3. Pobierz ze stosu stan i nazwij go S 4. Jesli

(a) S jest poszukiwanym stanem końcowym zwróć SUKCES i zakończ algo- rytm

(b) S=NULL (lista jest pusta) zwróć BRAK ROZWIAZANIA i zakończ al- gorytm

(c) S nie jest poszukiwanym stanem końcowym to generuj wszystkie możliwe stany następujące po S (które można wyprowadzić z S zgodnie z wcześniej ustalonymi regułami a które nie były już rozważane) i zapisz je do kolejki 5. Idz do 3

Zadanie polega na stwierdzeniu, czy w wyżej podanym grafie wierzchołki 1 i 5 są połączone.

Wykorzystywane funkcje:

make stos() - funkcja tworzy STOS

put stos(x) - funkcja dodaje element x na stos get stos() - funkcja pobiera elemet ze stosu

Oto przebieg wykonywania algorytmu:

(5)

Numer Krok Wykonywana Stan Odwiedzone etapu algorytmu operacja kolejki wierzchołki

1 1 make stos() NULL NULL

2 2 put stos(1) 1 1

3 3 S:=get stos() (S=1) NULL 1

Wykonywanie punktu (c)

4 4 put stos(2), put stos(6), 2 6 9 1 2 6 9 put stos(9)

5 5 Powrót do 3 2 6 9 1 2 6 9

6 3 S:=get stos() (S=9) 2 6 1 2 6 9

Wykonywanie punktu (c)

7 4 put stos(10) 2 6 10 1 2 6 9 10

8 5 Powrót do 3 2 6 10 1 2 6 9 10

9 3 S:=get stos() (S=10) 2 6 1 2 6 9 10

Wykonywanie punktu (c)

10 4 put stos(11) 2 6 11 1 2 6 9 10 11

11 5 Powrót do 3 2 6 11 1 2 6 9 10 11

12 3 S:=get stos() (S=11) 2 6 1 2 6 9 10 11 Wykonywanie punktu (c)

13 4 put stos(5) 2 6 5 1 2 5 6 9 10 11

14 5 Powrót do 3 2 6 5 1 2 5 6 9 10 11

15 3 S:=get stos() (S=5) 2 6 1 2 5 6 9 10 11

16 4 Wykonywanie punktu (a)

return(SUKCES) 2 6 1 2 5 6 9 10 11

W tak realizowanym algorytmie poruszamy się wzdłuż jednej krawędzi ale dla danego wierzchołka odwiedzamy wszystkich jego sąsiadów. Możemy skonstruować algorytm tak, aby z danego wierzchołka generować tylko jeden (wybrany) stan na- stępującey po nim. Wówczas algorytm będzie przebiegał następująco:

1. Utwórz STOS

2. Przyjmij S stan początkowy i zapisz na stos 3. Jesli

(a) S jest poszukiwanym stanem końcowym zwróć SUKCES i zakończ algo- rytm

(b) S=NULL (lista jest pusta) zwróć BRAK ROZWIAZANIA i zakończ al- gorytm

(c) S nie jest poszukiwanym stanem końcowym to:

i. jeśli istnieje możliwy stan następujący po S to S przyjmij ten stan i zapisz na stos

ii. w przeciwnym przypadku zdejmij element ze stosu, następnie S przyj-

(6)

Oto przebieg wykonywania algorytmu:

Numer Krok Wykonywana Stan Odwiedzone

etapu algorytmu operacja stosu wierzchołki

1 1 make stos() NULL NULL

2 2 S=1; put stos(S) 1 1

3 3 Wykonywanie punktu i 1 2 1 2

S=2; put stos(S)

4 4 Powrót do 3 1 2 1 2

5 3 Wykonywanie punktu i 1 2 3 1 2 3

S=3; put stos(S)

6 4 Powrót do 3 1 2 3 1 2 3

7 3 Wykonywanie punktu i 1 2 3 4 1 2 3 4

S=4; put stos(S)

8 4 Powrót do 3 1 2 3 4 1 2 3 4

9 3 Wykonywanie punktu i 1 2 3 4 5 1 2 3 4 5

S=5; put stos(S)

10 4 Powrót do 3 1 2 3 4 5 1 2 3 4 5

11 3 Wykonywanie punktu i 1 2 3 4 5 8 1 2 3 4 5 8

S=8; put stos(S)

12 4 Powrót do 3 1 2 3 4 5 8 1 2 3 4 5 8

13 3 Wykonywanie punktu i 1 2 3 4 5 8 7 1 2 3 4 5 8 7 S=7; put stos(S)

14 4 Powrót do 3 1 2 3 4 5 8 7 1 2 3 4 5 8 7

15 3 Wykonywanie punktu i 1 2 3 4 5 8 7 6 1 2 3 4 5 8 7 6 S=6; put stos(S)

16 4 Powrót do 3 1 2 3 4 5 8 7 6 1 2 3 4 5 8 7 6

17 3 Wykonywanie punktu ii 1 2 3 4 5 8 7 1 2 3 4 5 8 7 6 S=get stos() put stos(S) (S=7)

18 4 Powrót do 3 1 2 3 4 5 8 7 1 2 3 4 5 8 7 6

19 3 Wykonywanie punktu ii 1 2 3 4 5 8 1 2 3 4 5 8 7 6 S=get stos() put stos(S) (S=8)

20 4 Powrót do 3 1 2 3 4 5 8 1 2 3 4 5 8 7 6

21 3 Wykonywanie punktu ii 1 2 3 4 5 1 2 3 4 5 8 7 6

S=get stos(); put stos(S) (S=5)

22 4 Powrót do 3 1 2 3 4 5 1 2 3 4 5 8 7 6

23 3 Wykonywanie punktu i 1 2 3 4 5 11 1 2 3 4 5 8 7 6 11 S=11; put stos(S)

24 4 Powrót do 3 1 2 3 4 5 11 1 2 3 4 5 8 7 6 11

25 3 Wykonywanie punktu a 1 2 3 4 5 11 1 2 3 4 5 8 7 6 11 return(SUKCES)

Taki przebieg algorytmu oprócz odpowiedzi na pytanie czy dwa wierzchołki są ze sobą połączone, generuje drogę prowadzacą od wierzchołka początkowego do wierz- chołka końcowego (zwykle nie jest to optymalna droga). Jest to stan stosu w mo- mencie zakończenia działania algorytmu.

(7)

Zadania

Zadanie będą polegały na zastosowaniu powyższych algorytmów do sprawdzenia, czy dwa wierzchołki w grafie są ze sobą połączone.

Zadanie 1

Napisać program, w oparciu o padane algorytmy, sprawdzającey, czy dwa wierz- chołki w grafie są połączone. Zakładamy, ze program wczytuje graf z pliku o poda- nej w linii poleceń nazwie. Następnie pyta o numery wierzchołków do sprawdzenia.

Wierzchołki numerujemy liczbami naturalnymi z przedziału [1, 100]. W pliku pierw- sza linia zawiera liczbę wierzchołków, kolejne są listowym opisem grafu. Tak więc linia 2 zawiera sopis wierzchołków, z którymi łączy się wierzchołek 1, linia 3 - spis wierzchołków, z którymi łączy się wierzchołek 2, itd. Kolejne wierzchołki w linii rozdzielone są spacją. Każda linia na końcu zawiera liczbę 0, która oznacza koniec listy wierzchołków sąsiadujących z danym wierzchołkiem. Oto przykładowy plik z danymi dla rozważanego w przykładach grafu:

11 2 6 9 0 1 3 0 2 4 0 3 5 0 4 8 11 0 1 7 0 6 8 0 5 7 0 1 10 0 9 11 0 5 10 0

Zadanie 2

Napisać program, w oparciu o podany algorytm, sprawdzający czy możliwe jest przejście w labiryncie od jednego miejsca do drugiego. Zakładamy że program wczy- tuje labirynt z pliku o podanej w linii poleceń nazwie. Następnie pyta się o współ- rzędne pola startowego i końcowego. Maksymalny rozmiar planszy to 100 wierszy i 100 kolumn. Każde pole na planszy ma numer z przedziału [0, 15]. Numer ten oznacza jekiego typu jest pole, to znaczy gdzie możemy się z niego przemieścić. Oto dostępne pola (lewe górne ma numer 0, prawe dolne - 15, numeracja wierszami):

Rysunek 2: Pola labryntu.

(8)

spacjami. Oto przykładowy wygląd labiryntu i odpowiadającego mu pliku z danymi:

Rysunek 3: Plansza labiryntu.

4 5

8 9 12 8 5 4 5 14 2 13 4 3 9 0 5 13 15 15 7 6

Ilustrowany na ekranie - na przykład pola odwiedzone niech mają inny kolor. W realizacji tekstowej program powinien wyświetlać (lub zapisywać do pliku) współ- rzędne odwiedzanych pól.

Uwaga

Jak łatwo zauważyć labirynt można utożsamiać z grafem. Poszczególne pola la- biryntu są wierzchołkami, a rodzaj pola jednoznacznie definiuje listę wieszchołków sąsiadujących z rozważanym. Dla powyższego labiryntu plik opisujący go jako graf wygląda następująco:

20 2 6 0 1 3 0 2 0 5 9 0 4 10 0 1 7 11 0 6 12 0 9 0 4 8 14 0 5 0

6 12 16 0 7 11 13 0 12 14 0 9 13 15 19 0 14 20 0 11 0 0 0

14 20 0 15 19 0

Cytaty

Powiązane dokumenty

Wykonując ćwiczenie laboratoryjne zapoznasz się z jednym z dostępnych programów do two- rzenia i przeszukiwania grafów i zastosujesz do wybranych problemów

zastosowaniach, ze wzgl edu na wielko´s´c grafu, algorytm Dijkstry musi by´c ֒ wspomagany przez dodatkowe techniki.. Przeszukiwanie przestrzeni stan´ow mo˙zna prowadzi´c

Napisz algorytm o zªo»ono±ci O(n), gdzie n-liczba wierzchoªków danego grafu, który bada czy dany graf zorientowany reprezentowany przez macierz s¡siedztwa zawiera wierzchoªek,

Graf jest spójny, jeżeli z każdego wierzchołka da się dojść do wszystkich pozostałych. W przeciwnym wypadku graf jest określany jako

10 krawędzi musi pracowicie przeliczyć wszystkie wierzchołki leżące w odległości 1, potem 2, i tak dalej aż do odległości 9 od startowego, by mieć szansę znaleźć

Strategia z nawracaniem jest modyfikacją algorytmu przeszukiwania „w głąb”. Lista OPEN

Wska¿

tinua - dziejowy proces, w którym Lud Boży, uczestnicząc aż do końca czasów w Triduum Sacrum i Nocy Paschalnej, wkracza „w czas ostateczny, w czas oczekiwania na