I_R_W14_M38_C++ Podejście zachłanne. Najkrótsza droga w grafie
Implementacja algorytmu Dijkstry w języku C++
Program oblicza najkrótsze ścieżki od wybranego wierzchołka początkowego do wszystkich pozostałych wierzchołków grafu oraz zapisuje poprzedniki, dzięki którym można odtworzyć przebieg ścieżki.
Specyfikacja problemu:
Dane:
listaSasiedztwa – tablica opisująca graf nieskierowany i ważony;
Każdy element listaSasiedztwa[u][i]jest trójką:
indeks sąsiada wierzchołka
u,waga krawędzi prowadzącej z
udo tego sąsiada,lub
{-1, -1},jeśli brak połączenia.
s – numer wierzchołka startowego,
V– liczba wierzchołków w grafie.
Wynik:
d[]- tablica najkrótszych odległości od wierzchołka startowego,p[]- tablica poprzedników, która pozwala odtworzyć najkrótszą ścieżkę.
Działanie programu przetestujemy dla następującego grafu:

Przyjmijmy założenie, że wierzchołkiem początkowym jest wierzchołek E (o indeksie równym 4).
Opis działania algorytmu
Inicjalizacja
Wszystkie odległości ustawiane są na wartość „nieskończoność”.
Dla wierzchołka startowego
sustawiamyd[s] = 0.Tablica poprzedników
p[]wypełniona jest wartościami-1.Tablica
S[]oznacza, które wierzchołki zostały już odwiedzone.
Wybór wierzchołka o najmniejszym koszcie
Algorytm wybiera wierzchołek
u, który:nie został jeszcze odwiedzony,
ma najmniejszą wartość
d[u].
Dodanie wierzchołka do zbioru S
Wierzchołek
uzostaje oznaczony jako odwiedzony.
Relaksacja krawędzi
Dla każdego sąsiada
vwierzchołkausprawdzamy, czy:Jeśli tak:
aktualizujemy koszt
d[v],ustawiamy poprzednika
p[v] = u.
Zakończenie
Po odwiedzeniu wszystkich wierzchołków algorytm zwraca tablice
d[]ip[].
Algorytm Dijkstry działa zachłannie: w każdej iteracji wybiera wierzchołek o najmniejszej aktualnej odległości, który nie został jeszcze odwiedzony. Następnie wykonuje relaksację krawędzi, czyli sprawdza, czy przejście przez ten wierzchołek prowadzi do skrócenia drogi do jego sąsiadów.
Proces powtarza się, aż wszystkie wierzchołki zostaną odwiedzone lub nie ma już dostępnych wierzchołków.
Reprezentacja grafu
W programie graf jest zapisany jako macierz sąsiedztwa:
int waga[V][V];
Każdy element macierzy oznacza wagę krawędzi między wierzchołkami:
jeśli
waga[u][v] > 0→ istnieje krawędź zudovo tej wadze,jeśli
waga[u][v] == 0→ brak połączenia.
Ponieważ graf jest nieskierowany, macierz jest symetryczna:
waga[u][v] == waga[v][u]
Oto macierz sąsiedztwa grafu z naszego przykładu:
Interpretacja:
waga[0][1] = 1→ krawędź 0–1 o wadze 1waga[0][2] = 4→ krawędź 0–2 o wadze 4waga[1][4] = 1→ krawędź 1–4 o wadze 1waga[3][5] = 12→ krawędź 3–5 o wadze 12waga[u][v] = 0→ brak krawędzi
Kod w C++:
Wynik działania programu
Spróbuj ręcznie zweryfikować poprawność uzyskanego rozwiązania.
Słownik
suma wag wszystkich krawędzi, z których składa się ścieżka, droga lub cykl
graf, którego połączone krawędziami wierzchołki nie mają ustalonego kierunku, w którym można się po nich poruszać (są nieuporządkowane)
graf, w którym każda para wierzchołków połączona jest drogą
graf którego krawędzie mają przypisane wagi
nieuporządkowana para (niekoniecznie różnych) elementów zbioru wierzchołków, tj. takich, które są ze sobą połączone; w reprezentacji graficznej jest to linia łącząca te wierzchołki; krawędź może łączyć ze sobą jeden wierzchołek (wtedy nazywana jest pętlą)
zestaw V uporządkowanych list, gdzie lista o indeksie i jest listą wszystkich sąsiadów wierzchołka i
taka ścieżka łącząca dwa wierzchołki grafu, której suma wag krawędzi jest jak najmniejsza
liczba krawędzi incydentnych z danym wierzchołkiem
wartość przypisana krawędzi grafu
inaczej: punkt, węzeł; element niepustego zbioru, który wraz ze zbiorem krawędzi tworzy graf