Sortowanie Topologiczne jest bardzo przydatnym algorytmem podczas analizy grafu. W codziennym życiu można go zastosować do listy zadań zależnych od siebie, aby odkryć w jakiej kolejności powinny zostać wykonane. Tego typu sortowanie opiera się na algorytmie przeszukiwania grafu w głąb DFS.
Na początku należy wczytać graf skierowany, a następnie wykonać na nim algorytm DFS. Kolejny krok polega na posortowaniu wierzchołków według przypisanych do nich wartości post. W ten sposób uzyskuje się listę wierzchołków posortowaną topologicznie. Oznacza to, że jeśli narysuje się wierzchołki obok siebie w takiej kolejności jak na liście to wszystkie strzałki na grafie będą skierowane w prawo.
Dajmy na to, że mamy listę zadań do zrobienia. Jednak część zadań zależy od wykonania poprzednich czyli np. zadania B nie można wykonać przed zadaniem A. W tabelce zostały zebrane informacje dotyczące zadań i które poprzednie zadania muszą zostać wykonane, aby można je było wykonać:
Zadanie | Wymaga |
---|---|
A | - |
B | A |
C | - |
D | A, B |
E | C, D, F |
F | - |
Zadanie to można przedstawić przy pomocy grafu. Strzałka na grafie wskazuję w którą stronę przekazywana jest gotowość (tj. strzałka kończy się w zadaniu zależnym). Przykładowa organizacja wierzchołków wygląda następująco:
Na grafie panuje bałagan i ciężko odkryć, które zadanie wykonać jako pierwsze. Z tego powodu rozpoczynamy porządkowanie poprzez zastosowanie algorytmu DFS na grafie. Dokładny opis algorytmu można znaleźć tutaj. Poniżej zostały przedstawione znalezione wartości:
Wierzchołek | A | B | C | D | E | F |
---|---|---|---|---|---|---|
pre | 1 | 3 | 5 | 7 | 9 | 10 |
post | 2 | 4 | 6 | 8 | 12 | 11 |
Teraz należy posortować dane zgodnie z wartością post. Wtedy otrzymana kolejność to A, B, C, D, F, E. Zadanie E jest ostatnie, ponieważ wymaga wykonania zadania F i wszystkich poprzednich (nie widać tego bezpośrednio na grafie). Uoprządkowany graf przedstawia się następująco:
Program wczytuje od użytkownika graf jako macierz incydencji, która przechowuje informację o n wierzchołkach. Przykładowo graf przedstawiony w przykładzie zapisany jako macierz ma następującą reprezentację:
Część macierzy nie jest wykorzystana, ponieważ jest to graf skierowany.
Do przechowywania danych potrzebna jest struktura dane, która pozwala przechować id elementu, jego poprzednika, wartości pre i post oraz czy element był odwiedzony. Zwykle nie istnieje potrzeba przechowywania id, ale tablica będzie sortowana, więc niekoniecznie i-ty wierzchołek zostanie na i-tej pozycji.
Funkcja DFS rozpoczyna przeszukiwanie w głąb grafu: najpierw tworzona jest tablica danych i wypełniona zostaje domyślnymi wartościami. Następnie rozpoczyna się odwiedzanie kolejnych, według porządku alfabetycznego, wierzchołków grafu. Wynikiem działa funkcji jest tablica wierzchołków z uzupełnionymi o nich informacjach.
Proces odwiedzania wierzchołku polega na nadaniu mu wartości pre, a potem odwiedzeniu wszystkich nieodwiedzonych sąsiadów. Po zakończeniu odwiedzin należy pamiętać, aby nadać na koniec elementowi wartość post!
Teraz pozostaje napisać funkcję sortowania, która kolejno: (1.) zaakceptuje macierz grafu macierz i ilość wierzchołków n, a potem (2.) wykona na grafie algorytm DFS, (3.) posortuje dane i (4.) zwróci posortowaną tablicę.
Do sortowania została wbudowana w język funkcja do sortowania, ale należało dodać jak program ma porównać dwa elementy typu dane. Jako klucz została użyta wartość post porównywanych elementów.
Poniższy kod wczyta od użytkownika potrzebne informacje, a następnie wypisze na ekran wynik czyli posortowane numery wierzchołków grafu.