Podcast o Graf oraz przeszukiwanie wszerz i w głąb

Graf oraz Przeszukiwanie Wszerz i Wgłąb (BFS, DFS) – Poradnik

Podcast

Algorytmy Przeszukiwania Grafów: BFS i DFS0:00 / 11:51
0:001:00 pozostało
NataliaWyobraź sobie taką sytuację. Egzamin z informatyki, dostajesz zadanie z grafami i wiesz, że jest jeden błąd, który popełnia 80% studentów. Jeden mały błąd, który kosztuje masę punktów. A co, jeśli powiem ci, jak go unikać już na zawsze?
SzymonDokładnie o tym dzisiaj porozmawiamy. Ten jeden haczyk, który odróżnia tych, co zdają, od tych, co zdają na piątkę. To jest prostsze, niż myślisz.
Rozdziały

Algorytmy Przeszukiwania Grafów: BFS i DFS

Délka: 11 minut

Kapitoly

Wprowadzenie

Jak reprezentować grafy?

Przeszukiwanie wszerz – BFS

Przeszukiwanie w głąb – DFS

BFS kontra DFS

Najczęstsze pułapki

Podsumowanie

Přepis

Natalia: Wyobraź sobie taką sytuację. Egzamin z informatyki, dostajesz zadanie z grafami i wiesz, że jest jeden błąd, który popełnia 80% studentów. Jeden mały błąd, który kosztuje masę punktów. A co, jeśli powiem ci, jak go unikać już na zawsze?

Szymon: Dokładnie o tym dzisiaj porozmawiamy. Ten jeden haczyk, który odróżnia tych, co zdają, od tych, co zdają na piątkę. To jest prostsze, niż myślisz.

Natalia: Słuchacie Studyfi Podcast. Ja jestem Natalia, a ze mną ekspert, Szymon. No dobrze, Szymon, zacznijmy od totalnych podstaw. Czym w ogóle jest graf?

Szymon: Dobre pytanie! To nie jest wykres z Excela. W informatyce graf to zbiór wierzchołków — czyli kropek — i krawędzi, które je łączą. Pomyśl o mapie miast. Miasta to wierzchołki, a drogi między nimi to krawędzie.

Natalia: Proste. Czyli sieci społecznościowe to też graf? Ja i ty jesteśmy wierzchołkami, a nasza znajomość to krawędź?

Szymon: Dokładnie tak! I te krawędzie mogą mieć kierunek. Jeśli ja mogę do ciebie napisać, a ty do mnie nie, to jest to graf skierowany. A jeśli znajomość działa w obie strony, to graf jest nieskierowany.

Natalia: Rozumiem. A co z tymi grafami ważonymi? Brzmi skomplikowanie.

Szymon: Nic bardziej mylnego. Krawędź ważona ma po prostu przypisaną liczbę, czyli wagę. Na naszej mapie miast wagą może być odległość w kilometrach. W grafie nieważonym wszystkie drogi są równe.

Natalia: Okej, czyli mamy te kropki i linie. Ale jak komputer ma to zrozumieć? Jak to zapisać w kodzie?

Szymon: Są dwa główne sposoby. Pierwszy to macierz sąsiedztwa. To taka duża tabela, gdzie zapisujemy jedynkę, jeśli między dwoma wierzchołkami jest krawędź, i zero, jeśli jej nie ma.

Natalia: Brzmi logicznie. Jakieś wady?

Szymon: Ogromne. Jeśli masz tysiąc miast, ale tylko kilka dróg, to większość tej tabeli będzie wypełniona zerami. To straszne marnotrawstwo pamięci. Dobre tylko dla gęstych grafów, gdzie prawie każdy jest połączony z każdym.

Natalia: A druga opcja? Ta lepsza?

Szymon: Zdecydowanie częściej używana — lista sąsiedztwa. Dla każdego wierzchołka tworzymy po prostu listę jego sąsiadów. To o wiele bardziej oszczędne dla grafów z małą liczbą krawędzi, czyli tak zwanych grafów rzadkich.

Natalia: Czyli dla sieci znajomych, gdzie nikt nie zna wszystkich, lista sąsiedztwa jest idealna. A dla macierzy... może dla małej, zamkniętej grupy, gdzie każdy zna każdego?

Szymon: Dokładnie. Wybór reprezentacji to kluczowa decyzja, która wpływa na wydajność algorytmów. Zapamiętajcie: macierz dla gęstych grafów, lista dla rzadkich.

Natalia: Dobra, mamy nasz graf w pamięci. Teraz chcemy go przeszukać, czyli odwiedzić wszystkie wierzchołki. Słyszałam o dwóch głównych metodach: BFS i DFS. Zacznijmy od BFS.

Szymon: Jasne. BFS, czyli Breadth-First Search, to przeszukiwanie wszerz. Wyobraź sobie, że wrzucasz kamień do wody. Fala rozchodzi się równomiernie we wszystkich kierunkach, warstwa po warstwie. Tak właśnie działa BFS.

Natalia: Czyli zaczynam od jednego wierzchołka, odwiedzam wszystkich jego bezpośrednich sąsiadów, potem sąsiadów tych sąsiadów i tak dalej?

Szymon: Precyzyjnie. BFS używa do tego specjalnej struktury danych, która nazywa się kolejką. Działa na zasadzie "kto pierwszy przyjdzie, ten pierwszy wychodzi". Jak kolejka w sklepie.

Natalia: Okej, czyli dodaję wierzchołek startowy do kolejki. Potem go wyciągam, sprawdzam jego sąsiadów, dodaję ich na koniec kolejki i oznaczam jako odwiedzonych. I tak w kółko, aż kolejka będzie pusta?

Szymon: Dokładnie! I tu jest najważniejsza właściwość BFS: zawsze znajduje najkrótszą ścieżkę w grafie nieważonym. Najkrótszą, czyli taką z najmniejszą liczbą krawędzi.

Natalia: To jest super przydatne! Czyli jeśli szukam najszybszego połączenia metrem, gdzie każdy przystanek to jedna krawędź, to BFS da mi odpowiedź?

Szymon: Tak! Ponieważ eksploruje graf warstwami, to gdy po raz pierwszy dociera do celu, mamy gwarancję, że to najkrótsza możliwa droga pod względem liczby przystanków.

Natalia: Zobaczmy na przykładzie. Graf A-B, A-C, B-D. Startujemy z A. Do kolejki wrzucamy A.

Szymon: Dobrze. Wyciągamy A. Jego sąsiedzi to B i C. Wrzucamy B i C do kolejki. Kolejka teraz to .

Natalia: Teraz wyciągamy B. Jego sąsiad to D. Wrzucamy D do kolejki. Kolejka to .

Szymon: I tak dalej. Kolejność odwiedzin będzie: A, potem B i C, a na końcu D. Warstwami.

Natalia: Okej, BFS jest jak fala. Systematyczny i szeroki. Czym w takim razie jest DFS, czyli Depth-First Search?

Szymon: DFS to zupełnie inna filozofia. To przeszukiwanie w głąb. Wyobraź sobie, że jesteś w labiryncie. Idziesz jedną ścieżką tak daleko, jak się da. Jak trafisz w ślepy zaułek, cofasz się do ostatniego rozwidlenia i próbujesz innej drogi.

Natalia: Czyli to taki uparty odkrywca? Zamiast rozglądać się na boki, pędzi przed siebie?

Szymon: Dokładnie! DFS nie używa kolejki, tylko stosu. Stos działa na zasadzie "kto ostatni wejdzie, ten pierwszy wychodzi". Jak stos talerzy — zdejmujesz ten z samej góry.

Natalia: To kompletnie zmienia kolejność odwiedzin! W naszym grafie A-B, A-C, B-D, startując z A, co zrobi DFS?

Szymon: Startujemy z A. Na stos wrzucamy A. Zdejmujemy A, oznaczamy jako odwiedzone. Jego sąsiedzi to B i C. Wrzucamy ich na stos, powiedzmy C, potem B. Stos to .

Natalia: Zdejmujemy B. Jego sąsiad to D. Wrzucamy D na stos. Stos to .

Szymon: Teraz zdejmujemy D. Nie ma już nowych sąsiadów. Zdejmujemy C. Też koniec. Kolejność odwiedzin to A, B, D, a dopiero potem wracamy i sprawdzamy C. Widzisz różnicę? DFS poszedł w głąb ścieżki A-B-D.

Natalia: Wow, zupełnie inna trasa. Do czego w takim razie przydaje się DFS, skoro nie znajduje najkrótszej ścieżki?

Szymon: O, ma mnóstwo zastosowań! Jest świetny do wykrywania cykli w grafie, czyli czy da się wrócić do punktu wyjścia inną drogą. Używa się go też do rozwiązywania labiryntów czy w sortowaniu topologicznym, które jest kluczowe np. przy zarządzaniu zależnościami w projektach.

Natalia: Dobrze, podsumujmy te różnice, bo to chyba klucz do zrozumienia obu algorytmów.

Szymon: Jasne. Po pierwsze, struktura danych. BFS to kolejka, zasada FIFO - First In, First Out. DFS to stos, zasada LIFO - Last In, First Out.

Natalia: Po drugie, sposób przeszukiwania. BFS idzie wszerz, warstwa po warstwie. Jest płytki i szeroki. DFS idzie w głąb, jedną ścieżką do końca. Jest wąski i głęboki.

Szymon: Dokładnie. I to prowadzi do najważniejszej różnicy w zastosowaniach. Chcesz najkrótszą ścieżkę w grafie bez wag? Tylko BFS. Chcesz sprawdzić, czy w grafie jest cykl, albo rozwiązać labirynt? DFS będzie twoim przyjacielem.

Natalia: A złożoność? Czy któryś jest szybszy?

Szymon: Tutaj niespodzianka — oba mają taką samą złożoność czasową! Dla grafu reprezentowanego przez listę sąsiedztwa, oba działają w czasie O(V + E), gdzie V to liczba wierzchołków, a E to liczba krawędzi.

Natalia: Czyli w praktyce są równie szybkie, ale dają zupełnie inne wyniki i służą do czego innego. Wybór zależy od problemu, który chcemy rozwiązać.

Szymon: To jest sedno sprawy. Nie ma "lepszego" algorytmu. Jest tylko "lepiej dopasowany" do konkretnego zadania.

Natalia: Wróćmy do tego, od czego zaczęliśmy. Ten błąd, który popełnia 80% studentów. Co to jest?

Szymon: To aż boli, jak często to widzę. To zapominanie o oznaczaniu wierzchołków jako odwiedzonych. A dokładniej, oznaczanie ich w złym momencie.

Natalia: Jak to w złym momencie? Myślałam, że po prostu trzeba oznaczyć i już.

Szymon: W BFS wierzchołek powinno się oznaczać jako odwiedzony w momencie dodawania go do kolejki, a nie dopiero po wyjęciu go z niej. Jeśli zrobisz to za późno, a graf ma cykle, to ten sam wierzchołek może trafić do kolejki wiele razy. Algorytm wpadnie w pętlę albo będzie działał bardzo nieefektywnie.

Natalia: Aaa, czyli jeśli wierzchołek A jest połączony z B, a B z A, to bez oznaczania od razu, będą się dodawać do kolejki w nieskończoność?

Szymon: Dokładnie tak! To prowadzi do nieskończonej pętli i zwiechy programu. Prosty błąd, a konsekwencje fatalne. To jest właśnie ta pułapka.

Natalia: Jakaś inna częsta pomyłka?

Szymon: Tak, używanie BFS do szukania najkrótszej ścieżki w grafie z wagami. Pamiętajcie, BFS liczy tylko liczbę krawędzi. Jeśli jedna droga ma 5 przystanków i zajmuje 10 minut, a druga ma 2 przystanki i zajmuje godzinę, BFS wybierze tę drugą! Do grafów ważonych potrzebujemy innych algorytmów, jak algorytm Dijkstry.

Natalia: Czyli nie można bezmyślnie stosować jednego narzędzia do wszystkiego. Trzeba zrozumieć, jak działa i jakie ma ograniczenia.

Szymon: Właśnie. I trzeci błąd: pomylenie struktur danych. Użycie stosu do BFS albo kolejki do DFS. To tak jakbyś próbował wkręcić śrubę młotkiem. Może się uda, ale efekt będzie... ciekawy.

Natalia: Dobra, to było naprawdę dużo wiedzy, ale świetnie to wyjaśniłeś. Spróbujmy zebrać najważniejsze punkty dla naszych słuchaczy.

Szymon: Po pierwsze, grafy to wierzchołki i krawędzie. Możemy je reprezentować macierzą lub, co częstsze i lepsze dla rzadkich grafów, listą sąsiedztwa.

Natalia: Po drugie, mamy dwa główne algorytmy przeszukiwania. BFS, czyli przeszukiwanie wszerz, używa kolejki, rozchodzi się jak fala i jest idealny do znajdowania najkrótszej ścieżki w grafach nieważonych.

Szymon: A DFS, czyli przeszukiwanie w głąb, używa stosu, eksploruje jedną ścieżkę do samego końca i świetnie nadaje się do wykrywania cykli czy rozwiązywania labiryntów.

Natalia: I najważniejsze, ten kluczowy błąd do uniknięcia: zawsze oznaczaj wierzchołki jako odwiedzone, najlepiej od razu przy dodawaniu ich do kolejki lub stosu, żeby nie wpaść w nieskończoną pętlę. I nie używaj BFS do grafów z wagami!

Szymon: Jeśli to zapamiętacie, te 80% was nie dotyczy. Jesteście w tych 20%, które naprawdę rozumieją, co robią. To jest ta przewaga na egzaminie.

Natalia: Dokładnie tak. Dzięki wielkie, Szymon, za tę dawkę wiedzy!

Szymon: Cała przyjemność po mojej stronie. Do usłyszenia!

Natalia: A wy słuchaliście Studyfi Podcast. Powodzenia na egzaminach i do następnego razu!