Jak działa przeszukiwanie grafu w głąb?

Przeszukiwanie w głąb, nazywane w skrócie DFSDFSDFS, to jedna z metod przeszukiwania grafów nieskierowanych lub skierowanych. Jak sama nazwa wskazuje, algorytm przechodzi graf, sięgając tak głęboko, jak to tylko możliwe. Jeśli algorytm dotrze do wierzchołka, którego wszyscy sąsiedzi zostali już odwiedzeni, zawraca do ostatniego wierzchołka, który ma jeszcze nieodwiedzonych sąsiadów. Jest to działanie podobne do trawersowania drzewa w kolejności pre‑ordertrawersowanie pre‑ordertrawersowania drzewa w kolejności pre‑order.

Algorytm przeszukiwania w głąb przechodzi przez graf w sposób, który przypomina przemierzanie labiryntu. Po wybraniu wierzchołka startowego przechodzimy po kolejnych krawędziach najdalej, jak to tylko możliwe. W labiryncie nie zawracamy, dopóki mamy przed sobą jeszcze jakieś nieodwiedzone ścieżki. Robimy to dopiero wtedy, gdy trafimy na ślepy zaułek. Analogicznie podczas przeszukiwania w głąb odwiedzane są kolejne sąsiadujące ze sobą wierzchołki grafu, dopóki nie trafimy na wierzchołek, którego wszyscy sąsiedzi zostali już odwiedzeni. W takim wypadku cofamy się do poprzedniego wierzchołka posiadającego nieodwiedzonych sąsiadów i to od niego kontynuujemy przeszukiwanie.

Podczas przeszukiwania w głąb wykonywane są dwie zasadnicze czynności:

  1. oznaczanie wierzchołka jako odwiedzonego,

  2. badanie wierzchołka, czyli wywołanie rekurencyjnejrekurencjarekurencyjnej funkcji DFS() dla wszystkich sąsiednich wierzchołków nieodwiedzonych.

Polecenie 1

Zapoznaj się z prezentacją przedstawiającą przykład przeszukiwania grafu w głąb.

R11QmoLaNALec1
Wybierz jedno nowe słowo poznane podczas dzisiejszej lekcji i ułóż z nim zdanie.
Źródło: Contentplus.pl sp. z o.o., licencja: CC BY-SA 3.0.

Przeanalizujmy algorytm rekurencyjny przeszukiwania grafu w głąb zapisany za pomocą pseudokodu. Algorytm podzielono tu na dwie funkcje. Pierwsza z nich, czyli DFS(), jest wywoływana rekurencyjnie i zaznacza kolejne wierzchołki jako odwiedzone. Funkcja StartDFS() inicjalizuje wierzchołki grafu jako nieodwiedzone i uruchamia funkcję DFS(), począwszy od wierzchołka start.

Specyfikacja:

Dane:

  • listaSasiedztwa – lista sąsiedztwa reprezentująca przeszukiwany graf

  • V – liczba naturalna dodatnia; liczba wierzchołków grafu

Wynik:

  • odwiedzoneV-elementowa tablica zawierająca listę wierzchołków wypisanych w kolejności odwiedzin

Linia 1. graf reprezentuje lista sąsiedztwa cudzysłów listaSasiedztwa cudzysłów. Linia 3. funkcja DFS otwórz nawias okrągły v zamknij nawias okrągły dwukropek. Linia 4. wypisz v. Linia 5. oznacz wierzchołek cudzysłów v cudzysłów jako odwiedzony. Linia 6. dla każdego cudzysłów w cudzysłów z listaSasiedztwa otwórz nawias kwadratowy v zamknij nawias kwadratowy wykonuj dwukropek. Linia 7. jeżeli wierzchołek cudzysłów w cudzysłów nie został odwiedzony dwukropek. Linia 8. DFS otwórz nawias okrągły w zamknij nawias okrągły. Linia 10. funkcja startDFS otwórz nawias okrągły start zamknij nawias okrągły dwukropek. Linia 11. oznacz wszystkie wierzchołki grafu jako nieodwiedzone. Linia 12. DFS otwórz nawias okrągły start zamknij nawias okrągły.

Zwykle wierzchołki oznaczamy jako odwiedzone w tablicy (nazwanej w pseudokodzie odwiedzone), w której i-ty wyraz odpowiada wierzchołkowi o indeksie i. Jeśli wartość odwiedzone[i] jest równa prawda, oznacza to, że wierzchołek został odwiedzony. W przeciwnym razie wierzchołek uznajemy za nieodwiedzony. Oto zapisany za pomocą pseudokodu program przeszukiwania w głąb, korzystający z takiej tablicy:

Linia 1. graf reprezentuje lista sąsiedztwa cudzysłów listaSasiedztwa cudzysłów. Linia 2. utwórz tablicę odwiedzone otwórz nawias kwadratowy 0 kropka kropka V minus 1 zamknij nawias kwadratowy. Linia 4. funkcja DFS otwórz nawias okrągły v zamknij nawias okrągły dwukropek. Linia 5. wypisz v. Linia 6. odwiedzone otwórz nawias kwadratowy v zamknij nawias kwadratowy ← prawda. Linia 7. dla każdego cudzysłów w cudzysłów z listaSasiedztwa otwórz nawias kwadratowy v zamknij nawias kwadratowy wykonuj dwukropek. Linia 8. jeżeli odwiedzone otwórz nawias kwadratowy w zamknij nawias kwadratowy znak równości fałsz dwukropek. Linia 9. DFS otwórz nawias okrągły w zamknij nawias okrągły. Linia 11. funkcja startDFS otwórz nawias okrągły start zamknij nawias okrągły dwukropek. Linia 12. dla i znak równości 0 przecinek 1 przecinek kropka kropka kropka przecinek V minus 1 wykonuj dwukropek. Linia 13. odwiedzone otwórz nawias kwadratowy i zamknij nawias kwadratowy ← fałsz. Linia 14. DFS otwórz nawias okrągły start zamknij nawias okrągły.

Istnieje iteracyjna wersja algorytmu przeszukiwania grafu w głąb, która korzysta ze stosustosstosu LIFO, przechowującego indeksy wierzchołków. Oto przykład zapisanego za pomocą pseudokodu iteracyjnego algorytmu DFS:

Linia 1. graf reprezentuje lista sąsiedztwa cudzysłów listaSasiedztwa cudzysłów. Linia 2. utwórz tablicę odwiedzone otwórz nawias kwadratowy 0 kropka kropka V minus 1 zamknij nawias kwadratowy. Linia 4. funkcja iteracyjnyDFS otwórz nawias okrągły start zamknij nawias okrągły dwukropek. Linia 5. dla i znak równości 0 przecinek 1 przecinek kropka kropka kropka przecinek V minus 1 wykonuj dwukropek. Linia 6. odwiedzone otwórz nawias kwadratowy i zamknij nawias kwadratowy ← fałsz. Linia 8. utwórz pusty stos cudzysłów stos cudzysłów. Linia 9. dodaj wierzchołek cudzysłów start cudzysłów na stos. Linia 10. dopóki rozmiar otwórz nawias okrągły stos zamknij nawias okrągły zamknij nawias ostrokątny 0 wykonuj dwukropek. Linia 11. v ← zdejmij wierzchołek z góry stosu. Linia 12. wypisz v. Linia 13. odwiedzone otwórz nawias kwadratowy v zamknij nawias kwadratowy ← prawda. Linia 14. dla każdego cudzysłów w cudzysłów z listaSasiedztwa otwórz nawias kwadratowy v zamknij nawias kwadratowy wykonuj dwukropek. Linia 15. jeżeli odwiedzone otwórz nawias kwadratowy w zamknij nawias kwadratowy znak równości fałsz dwukropek. Linia 16. dodaj wierzchołek cudzysłów w cudzysłów na stos.

Słownik

DFS
DFS

ang. depth‑first search – algorytm przeszukiwania/przejścia grafu w głąb polegający na przechodzeniu przez wierzchołki, do których prowadzą ścieżki; algorytm DFS gwarantuje, że żaden wierzchołek nie zostanie pominięty

rekurencja
rekurencja

technika programowania, w której funkcja wywołuje samą siebie, aż do napotkania przypadku podstawowego, czyli takiego, którego nie da się rozłożyć na mniejsze problemy; przykład przypadku podstawowego dla obliczania piątego wyrazu ciągu Fibonacciego:

fib4=fib3+fib2=fib2+fib1+fib1+fib0= 
=fib1+fib0+fib1+fib1+fib0=
=1+0 + 1+1+0=3
stos
stos

dynamiczna struktura danych, dla której możemy dodać nowy element jedynie na samym szczycie; usuwanie elementów ze stosu ma podobną formę co dodawanie, ponieważ możemy usunąć element znajdujący się tylko na szczycie

trawersowanie pre‑order
trawersowanie pre‑order

odwiedzenie węzłów drzewa w określonej kolejności: przechodząc najpierw przez korzeń, później lewe poddrzewo korzenia, a następnie prawe poddrzewo korzenia.