Algorytm przeszukiwania grafu wszerz (BFS) może służyć do sprawdzenia czy dany graf jest spójny, albo do znalezienia najkrótszej drogi pomiędzy dwoma wybranymi wierzchołkami grafu. Bardzo często jest on również wykorzystywany do sprawdzenia czy dany graf jest dwudzielny.
Algorytm Poszukiwania Wszerz wymaga określenia punktu początkowego oraz przypisania każdemu wierzchołkowi dwóch właściwości: odległość o wartości początkowej nieskończoność, oraz poprzednik, który początkowo jest pusty. Wyjątkiem jest punkt startowy, którego odległość początkowa wynosi 0. Początkowo kolejka składa się tylko z punktu początkowego.
Dopóki kolejka nie jest pusta pobieramy pierwszy jej element (usuwając go z kolejki). Następnie sprawdzamy, który z jego sąsiadów nie został odwiedzony tzn. nie ma ustawionego poprzednika. Sąsiadów wybieramy alfabetycznie (lub rosnąco) jeśli nie zostało wskazane inaczej w zadaniu. Dla każdego nieodwiedzonego dotychczas sąsiada ustawiamy odległość na odległość wybranego elementu z kolejki i dodajemy wagę krawędzi (dla grafu bez wag przyjmujemy 1) i ustawiamy poprzednika na aktualnie wybrany element. Algorytm kończy się, gdy kolejka będzie pusta.
Przypuśćmy, że mam następujący graf:
Punktem początkowym jest zaznaczony punkt A. W tabeli została przedstawiona aktualna kolejka oraz właściwości poszczególnych obiektów:
Kolejka | A | B | C | D | E | F | G | H | Dodane do kolejki |
---|---|---|---|---|---|---|---|---|---|
- | 0, - | ∞, - | ∞, - | ∞, - | ∞, - | ∞, - | ∞, - | ∞, - | - |
A | 0, - | 1, A | 1, A | 1, A | ∞, - | ∞, - | ∞, - | ∞, - | B, C, D |
B, C, D | 0, - | . | . | . | 2, B | ∞, - | ∞, - | ∞, - | E |
C, D, E | 0, - | . | . | . | . | 2, C | ∞, - | ∞, - | F |
D, E, F | 0, - | . | . | . | . | . | ∞, - | ∞, - | - |
E, F | 0, - | . | . | . | . | . | ∞, - | ∞, - | - |
F | 0, - | . | . | . | . | . | ∞, - | ∞, - | - |
- | 0, - | 1, A | 1, A | 1, A | 2, B | 2, C | ∞, - | ∞, - | - |
Z tabeli można wyczytać, że w odległości 1 od punktu początkowego A znajdują się węzły B, C oraz D, a w odległości 2 węzły E, F. Warto zwrócić uwagę, że do punktu F można dojść w drogą tej samej długości idąc kolejno A > C > F, albo A > D > F. Punkty G i H nie zostały odwiedzone, więc nie istnieje żadna droga do nich z węzła A. To świadczy również o tym, że graf nie jest spójny.
Napisz funkcję BFS, która na podstawie podanej macierzy sąsiedztwa oraz początkowego wypisze tablice z informacjami jak daleko jest z punktu początkowego do danego i który węzeł jest poprzednikiem. Przetestuj działanie funkcji.
Dane dotyczące węzła tj. jego odległość oraz poprzednik będą przechowywane w specjalnym typie.
Dane dotyczące węzła tj. jego odległość oraz poprzednik będą przechowywane w specjalnym typie.
Oto przykładowe rozwiązanie funkcji realizującej algorytm BFS.
(2. - 4.) Przygotuj tabelę na zapis informacji o przejściach i (5.) oznacz punkt początkowy. Następnie (6.) utwórz kolejke i (7.) włóż do niej węzeł początkowy. (8.) Dopóki kolejka nie jest pusta (9.) pobierz pierwszy element z kolejki i (10.) rozpocznij sprawdzanie jego sąsiadów. Jeśli (11.) krawędź do sąsiada istnieje i nie był odwiedzony to (12. - 13.) odwiedź go i (14.) dołącz na koniec kolejki.
Do przetestowania napisanej funkcji można skorzystać z poniższego fragmentu kodu, który wczytuje od użytkownika potrzebne dane, a następnie wypisuje odpowiednio sformatowany wynik.
Do ładnego sformatowania danych dotyczących węzła została dopisana funkcja wypiszdane(). Rozpoznaje ona niektóre wartości domyślne i na tej podstawie wyświetla odpowiedni opis zamiast liczb.
W celu przetestowania grafu przedstawionego w przykładzie należałoby podać n = 8, s = 0 oraz wpisać nastepującą macierz: