W tej sekcji znajdziesz przykłady implementacji reprezentacji grafów nieskierowanych bez wag w języku Python. Reprezentacje te zostały przedstawione w e‑materiale teoretycznymPpkZaFlK1e‑materiale teoretycznym, są to macierz sąsiedztwa, lista sąsiedztwa, macierz incydencji.
Grafy nieskierowane
Macierz sąsiedztwa
Dany jest następujący graf spójny nieskierowany bez wag:
R1OA3UoJEctUA
Jego macierz sąsiedztwamacierz sąsiedztwamacierz sąsiedztwa wygląda tak:
R12LrCWhJbLTN
Najprostszym sposobem przechowywania macierzy sąsiedztwa jest użycie tablicy dwuwymiarowej, która w języku Python odpowiada zagnieżdżonym listom.
Może się zdarzyć, że program rozpocznie pracę od grafu niezawierającego żadnych krawędzi, którego reprezentacja to po prostu macierz wypełniona samymi zerami. W takim przypadku możemy wygenerować listę składaną z użyciem funkcji range().
Na potrzeby naszej implementacji macierz sąsiedztwa będzie dwuwymiarową tablicą statyczną o V wierszach i V kolumnach (V to liczba wierzchołków grafu).
Linia 1. macierzSasiedztwa znak równości otwórz nawias kwadratowy otwórz nawias kwadratowy 0 zamknij nawias kwadratowy asterysk n for podkreślnik in range otwórz nawias okrągły V zamknij nawias okrągły zamknij nawias kwadratowy.
Po zastosowaniu przedstawionego kodu:
Linia 1. V znak równości 6.
Linia 2. macierzSasiedztwa znak równości otwórz nawias kwadratowy otwórz nawias kwadratowy 0 zamknij nawias kwadratowy asterysk V for podkreślnik in range otwórz nawias okrągły V zamknij nawias okrągły zamknij nawias kwadratowy.
Linia 3. for wiersz in macierzSasiedztwa dwukropek print otwórz nawias okrągły wiersz zamknij nawias okrągły.
Łączenie wierzchołków grafu nieskierowanego nowymi krawędziami zrealizujemy, odwołując się do odpowiednich wyrazów listy. Aby to zrobić, należy wyrazom macierzSasiedztwa[i][j] i macierzSasiedztwa[j][i] przypisać wartość 1.
Zmienne i oraz j to indeksy łączonych wierzchołków.
Linia 1. macierzSasiedztwa otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy j zamknij nawias kwadratowy znak równości 1.
Linia 2. macierzSasiedztwa otwórz nawias kwadratowy j zamknij nawias kwadratowy otwórz nawias kwadratowy i zamknij nawias kwadratowy znak równości 1.
Linia 3. for wiersz in macierzSasiedztwa dwukropek print otwórz nawias okrągły wiersz zamknij nawias okrągły.
Napiszmy program, który pozwoli nam obserwować, jak zmieniają się macierze sąsiedztwa. Najpierw wyświetli pierwotną macierz, a po dodaniu nowej krawędzi - nową macierz.
Linia 1. macierzSasiedztwa znak równości otwórz nawias kwadratowy.
Linia 2. otwórz nawias kwadratowy 0 przecinek 1 przecinek 1 przecinek 0 przecinek 1 przecinek 0 zamknij nawias kwadratowy przecinek.
Linia 3. otwórz nawias kwadratowy 1 przecinek 0 przecinek 1 przecinek 0 przecinek 1 przecinek 0 zamknij nawias kwadratowy przecinek.
Linia 4. otwórz nawias kwadratowy 1 przecinek 1 przecinek 0 przecinek 1 przecinek 0 przecinek 1 zamknij nawias kwadratowy przecinek.
Linia 5. otwórz nawias kwadratowy 0 przecinek 0 przecinek 1 przecinek 0 przecinek 1 przecinek 0 zamknij nawias kwadratowy przecinek.
Linia 6. otwórz nawias kwadratowy 1 przecinek 1 przecinek 0 przecinek 1 przecinek 0 przecinek 1 zamknij nawias kwadratowy przecinek.
Linia 7. otwórz nawias kwadratowy 0 przecinek 0 przecinek 1 przecinek 0 przecinek 1 przecinek 0 zamknij nawias kwadratowy.
Linia 8. zamknij nawias kwadratowy.
Linia 9. print otwórz nawias okrągły cudzysłów Pierwotna postac dwukropek cudzysłów zamknij nawias okrągły.
Linia 10. for wiersz in macierzSasiedztwa dwukropek print otwórz nawias okrągły wiersz zamknij nawias okrągły.
Linia 11. macierzSasiedztwa otwórz nawias kwadratowy 0 zamknij nawias kwadratowy otwórz nawias kwadratowy 5 zamknij nawias kwadratowy znak równości 1.
Linia 12. macierzSasiedztwa otwórz nawias kwadratowy 5 zamknij nawias kwadratowy otwórz nawias kwadratowy 0 zamknij nawias kwadratowy znak równości 1.
Linia 13. print otwórz nawias okrągły cudzysłów Polacz wierzcholki 0 i 5 dwukropek cudzysłów zamknij nawias okrągły.
Linia 14. for wiersz in macierzSasiedztwa dwukropek print otwórz nawias okrągły wiersz zamknij nawias okrągły.
Linia 15. macierzSasiedztwa otwórz nawias kwadratowy 2 zamknij nawias kwadratowy otwórz nawias kwadratowy 4 zamknij nawias kwadratowy znak równości 1.
Linia 16. macierzSasiedztwa otwórz nawias kwadratowy 4 zamknij nawias kwadratowy otwórz nawias kwadratowy 2 zamknij nawias kwadratowy znak równości 1.
Linia 17. print otwórz nawias okrągły cudzysłów Polacz wierzcholki 2 i 4 dwukropek cudzysłów zamknij nawias okrągły.
Linia 18. for wiersz in macierzSasiedztwa dwukropek print otwórz nawias okrągły wiersz zamknij nawias okrągły.
W konsoli program wypisze następujące wyrazy macierzy:
Przyjrzyjmy się graficznemu przedstawieniu wyniku.
Tak wygląda pierwotna postać macierzy:
RMZb5uA3j5aOO
Chcemy połączyć wierzchołki 0 oraz 5:
RVITL4mqUTBis
Po połączeniu wierzchołków macierz wygląda następująco:
Rue4hjdslZXQk
W przypadku łączenia innych wierzchołków sytuacja wygląda analogicznie.
Lista sąsiedztwa
Dany jest następujący graf spójny nieskierowany bez wag:
R1OA3UoJEctUA
Jego lista sąsiedztwa wygląda następująco:
Rri8wpXPrqHIU
Słownik w języku Python to nieuporządkowany zbiór wartości, służący do przechowywania danych. W przeciwieństwie do innych struktur danych (których poszczególne elementy są pojedynczymi wartościami) słownik przechowuje pary klucz: wartość.
Słownik może stanowić reprezentację grafu w postaci listy sąsiedztwalista sąsiedztwalisty sąsiedztwa, o ile za klucz przyjmiemy nazwę wierzchołka, a lista jego sąsiadów będzie wartością dla tego klucza. Sam wierzchołek możemy uczynić obiektem dowolnego typu.
Linia 1. listaSasiedztwa znak równości otwórz nawias klamrowy.
Linia 2. apostrof A apostrof dwukropek otwórz nawias kwadratowy apostrof B apostrof przecinek apostrof C apostrof zamknij nawias kwadratowy przecinek.
Linia 3. apostrof B apostrof dwukropek otwórz nawias kwadratowy apostrof A apostrof przecinek apostrof C apostrof przecinek apostrof D apostrof zamknij nawias kwadratowy przecinek.
Linia 4. apostrof C apostrof dwukropek otwórz nawias kwadratowy apostrof A apostrof przecinek apostrof B apostrof przecinek apostrof D apostrof przecinek apostrof E apostrof zamknij nawias kwadratowy przecinek.
Linia 5. apostrof D apostrof dwukropek otwórz nawias kwadratowy apostrof B apostrof przecinek apostrof C apostrof zamknij nawias kwadratowy przecinek.
Linia 6. apostrof E apostrof dwukropek otwórz nawias kwadratowy apostrof C apostrof przecinek apostrof F apostrof zamknij nawias kwadratowy przecinek.
Linia 7. apostrof F apostrof dwukropek otwórz nawias kwadratowy apostrof E apostrof zamknij nawias kwadratowy.
Linia 8. zamknij nawias klamrowy.
Ciekawostka
Należy pamiętać, że w przypadku słowników metoda iter() odwołuje się do kluczy. Oznacza to, że jeśli umieścimy słownik wewnątrz pętli for, metoda iter() będzie zwracać kolejne referencje do kluczy.
Linia 1. listaSasiedztwa znak równości otwórz nawias klamrowy apostrof A apostrof dwukropek otwórz nawias kwadratowy apostrof B apostrof zamknij nawias kwadratowy przecinek apostrof B apostrof dwukropek otwórz nawias kwadratowy apostrof A apostrof przecinek apostrof C apostrof zamknij nawias kwadratowy przecinek apostrof C apostrof dwukropek otwórz nawias kwadratowy apostrof B apostrof zamknij nawias kwadratowy zamknij nawias klamrowy.
Linia 2. for klucz in listaSasiedztwa dwukropek print otwórz nawias okrągły klucz zamknij nawias okrągły.
Wynik działania programu:
Linia 1. A.
Linia 2. B.
Linia 3. C.
Linia 1. listaSasiedztwa znak równości otwórz nawias klamrowy apostrof A apostrof dwukropek otwórz nawias kwadratowy apostrof B apostrof zamknij nawias kwadratowy przecinek apostrof B apostrof dwukropek otwórz nawias kwadratowy apostrof A apostrof przecinek apostrof C apostrof zamknij nawias kwadratowy przecinek apostrof C apostrof dwukropek otwórz nawias kwadratowy apostrof B apostrof zamknij nawias kwadratowy zamknij nawias klamrowy.
Linia 2. for klucz in listaSasiedztwa dwukropek print otwórz nawias okrągły listaSasiedztwa otwórz nawias kwadratowy klucz zamknij nawias kwadratowy zamknij nawias okrągły.
Wynik działania programu:
Linia 1. otwórz nawias kwadratowy apostrof B apostrof zamknij nawias kwadratowy.
Linia 2. otwórz nawias kwadratowy apostrof A apostrof przecinek apostrof C apostrof zamknij nawias kwadratowy.
Linia 3. otwórz nawias kwadratowy apostrof B apostrof zamknij nawias kwadratowy.
Dodawanie nowych wierzchołków do listy sąsiadów zrealizujemy dzięki metodzie append(), która dołącza nowy element do końca listy.
Linia 1. listaSasiedztwa otwórz nawias kwadratowy apostrof A apostrof zamknij nawias kwadratowy kropka append otwórz nawias okrągły apostrof C apostrof zamknij nawias okrągły.
Linia 2. for klucz in listaSasiedztwa dwukropek print otwórz nawias okrągły listaSasiedztwa otwórz nawias kwadratowy klucz zamknij nawias kwadratowy zamknij nawias okrągły.
Wynik działania programu:
Linia 1. otwórz nawias kwadratowy apostrof B apostrof przecinek apostrof C apostrof zamknij nawias kwadratowy.
Linia 2. otwórz nawias kwadratowy apostrof A apostrof przecinek apostrof C apostrof zamknij nawias kwadratowy.
Linia 3. otwórz nawias kwadratowy apostrof B apostrof zamknij nawias kwadratowy.
Wróćmy do przykładu. Dany jest pewien graf, którego reprezentacją jest lista sąsiedztwa (przechowywana za pomocą struktury danych, którą nazywamy słownikiem). By połączyć ze sobą wierzchołki, wykorzystamy opisaną wyżej metodę append(). Połączymy wierzchołki 0 i 5 oraz 2 i 4. Mamy do czynienia z grafem nieskierowanym, zatem do listy sąsiadów wierzchołka 0 dodamy wierzchołek 5, a do listy sąsiadów wierzchołka 5 dodamy wierzchołek 0. Analogicznie postąpimy z drugą parą wierzchołków.
Bardzo często trzeba rozpocząć program od pustej macierzy incydencji, do której w dalszych etapach pracy dodaje się nowe wyrazy. Aby zdefiniować taka pustą macierz w języku Python, zainicjalizujemy listę pustych list.
Linia 1. macierzIncydencji znak równości otwórz nawias kwadratowy otwórz nawias kwadratowy zamknij nawias kwadratowy for podkreślnik in range otwórz nawias okrągły V zamknij nawias okrągły zamknij nawias kwadratowy.
Łączenie wierzchołków nowymi krawędziami można zrealizować na wiele sposobów. Jeden z nich polega na dodaniu do każdej z list wewnątrz listy macierzIncydencji elementu zerowego, z wyjątkiem list na pozycjach i oraz j, odpowiadających wierzchołkom, które chcemy połączyć.
Linia 1. def polaczWierzcholek otwórz nawias okrągły macierzIncydencji przecinek i przecinek j zamknij nawias okrągły dwukropek.
Linia 2. for wiersz in macierzIncydencji dwukropek.
Linia 3. wiersz kropka append otwórz nawias okrągły 0 zamknij nawias okrągły.
Linia 5. macierzIncydencji otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy minus 1 zamknij nawias kwadratowy znak równości 1.
Linia 6. macierzIncydencji otwórz nawias kwadratowy j zamknij nawias kwadratowy otwórz nawias kwadratowy minus 1 zamknij nawias kwadratowy znak równości 1.
Macierz incydencji w takim przypadku zmienia swój rozmiar w zależności od rzeczywistej liczby krawędzi.
Kod programu:
Linia 1. def polaczWierzcholki otwórz nawias okrągły macierzIncydencji przecinek i przecinek j zamknij nawias okrągły dwukropek.
Linia 2. for wiersz in macierzIncydencji dwukropek.
Linia 3. wiersz kropka append otwórz nawias okrągły 0 zamknij nawias okrągły.
Linia 5. macierzIncydencji otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy minus 1 zamknij nawias kwadratowy znak równości 1.
Linia 6. macierzIncydencji otwórz nawias kwadratowy j zamknij nawias kwadratowy otwórz nawias kwadratowy minus 1 zamknij nawias kwadratowy znak równości 1.
Linia 8. macierzIncydencji znak równości otwórz nawias kwadratowy.
Linia 9. otwórz nawias kwadratowy 1 przecinek 1 przecinek 1 przecinek 0 przecinek 0 przecinek 0 przecinek 0 przecinek 0 przecinek 0 zamknij nawias kwadratowy przecinek.
Linia 10. otwórz nawias kwadratowy 1 przecinek 0 przecinek 0 przecinek 1 przecinek 1 przecinek 0 przecinek 0 przecinek 0 przecinek 0 zamknij nawias kwadratowy przecinek.
Linia 11. otwórz nawias kwadratowy 0 przecinek 1 przecinek 0 przecinek 1 przecinek 0 przecinek 1 przecinek 1 przecinek 0 przecinek 0 zamknij nawias kwadratowy przecinek.
Linia 12. otwórz nawias kwadratowy 0 przecinek 0 przecinek 0 przecinek 0 przecinek 0 przecinek 1 przecinek 0 przecinek 1 przecinek 0 zamknij nawias kwadratowy przecinek.
Linia 13. otwórz nawias kwadratowy 0 przecinek 0 przecinek 1 przecinek 0 przecinek 1 przecinek 0 przecinek 0 przecinek 1 przecinek 1 zamknij nawias kwadratowy przecinek.
Linia 14. otwórz nawias kwadratowy 0 przecinek 0 przecinek 0 przecinek 0 przecinek 0 przecinek 0 przecinek 1 przecinek 0 przecinek 1 zamknij nawias kwadratowy.
Linia 15. zamknij nawias kwadratowy.
Linia 16. print otwórz nawias okrągły cudzysłów Pierwotna postac dwukropek cudzysłów zamknij nawias okrągły.
Linia 17. for wiersz in macierzIncydencji dwukropek print otwórz nawias okrągły wiersz zamknij nawias okrągły.
Linia 19. print otwórz nawias okrągły cudzysłów Polacz wierzcholki 0 i 5 dwukropek cudzysłów zamknij nawias okrągły.
Linia 20. polaczWierzcholki otwórz nawias okrągły macierzIncydencji przecinek 0 przecinek 5 zamknij nawias okrągły.
Linia 21. for wiersz in macierzIncydencji dwukropek print otwórz nawias okrągły wiersz zamknij nawias okrągły.
Linia 23. print otwórz nawias okrągły cudzysłów Polacz wierzcholki 2 i 4 dwukropek cudzysłów zamknij nawias okrągły.
Linia 24. polaczWierzcholki otwórz nawias okrągły macierzIncydencji przecinek 2 przecinek 4 zamknij nawias okrągły.
Linia 25. for wiersz in macierzIncydencji dwukropek print otwórz nawias okrągły wiersz zamknij nawias okrągły.
Zwróć uwagę, że po prawej stronie pojawiły się nowe kolumny – odpowiadają one nowo powstałym krawędziom grafu.
Słownik
graf
graf
struktura składająca się z niepustego zbioru wierzchołków oraz rodziny krawędzi; dla grafu G zbiór wierzchołków oznaczamy jako V(G) (ang. verticies – wierzchołki), a zbiór krawędzi – E(G) (ang. edges – krawędzie); liczbę elementów zbioru V(G) oznaczamy literą n; liczbę elementów zbioru E(G) – m (oprac. na podst.: R. Wilson, Wprowadzenie do teorii grafów, PWN, Warszawa 2007)
graf spójny
graf spójny
graf, którego nie można przedstawić w postaci sumy dwóch grafów (oprac. na podst.: R. Wilson, Wprowadzenie do teorii grafów, PWN, Warszawa 2007)
graf ważony
graf ważony
graf ważony (inaczej graf z wagami) to taki graf, w którym każdej krawędzi przypisana jest pewna wartość liczbowa
izomorfizm
izomorfizm
własność grafów mówiąca o tym, że liczba krawędzi łączących dane dwa wierzchołki jednego grafu jest równa liczbie krawędzi łączących odpowiadające im wierzchołki drugiego grafu (oprac. na podst.: R. Wilson, Wprowadzenie do teorii grafów, PWN, Warszawa 2007)
krawędź
krawędź
nieuporządkowana para (niekoniecznie różnych) elementów zbioru wierzchołków (oprac. na podst.: R. Wilson, Wprowadzenie do teorii grafów, PWN, Warszawa 2007)
lista sąsiedztwa
lista sąsiedztwa
zestaw uporządkowanych list, gdzie lista o indeksie jest listą wszystkich sąsiadów wierzchołka
macierz
macierz
dwuwymiarowa tablica elementów (zwykle liczbowych), licząca wierszy i kolumn
macierz incydencji
macierz incydencji
macierz zerojedynkowa rozmiaru , dla której każda krawędź grafu musi mieć unikatowy indeks; wyraz jest równy , o ile krawędź o indeksie jest incydentna do wierzchołka
macierz sąsiedztwa
macierz sąsiedztwa
macierz zerojedynkowa rozmiaru , w której wyraz jest równy , jeśli wierzchołki oraz są sąsiednie, a w przeciwnym przypadku; macierz sąsiedztwa jest symetryczna dla grafów nieskierowanych
pętla zasięgu (zakresowa)
pętla zasięgu (zakresowa)
pętla for pozwalająca iterować przez zdefiniowany zakres
stopień wierzchołka
stopień wierzchołka
liczba krawędzi incydentnych z danym wierzchołkiem (oprac. na podst.: R. Wilson, Wprowadzenie do teorii grafów, PWN, Warszawa 2007)
wierzchołek
wierzchołek
pojedynczy punkt w przestrzeni; od niego wychodzą i w nim łączą się krawędzie