Stopnie grafu - implementacja
By w pełni zrozumieć zagadnienia poruszane w tym rozdziale, musimy znać kilka podstawowych pojęć:
stopień grafu,
stopień wierzchołka grafu,
spójność grafu.
Zaczniemy od stopnia grafu – jest on równy maksymalnemu stopniowi wierzchołka w tym grafie.
Stopniem wierzchołka grafu nieskierowanego nazywamy liczbę krawędzi z nim incydentnych.
Jeśli w grafie nieskierowanym występuje krawędź, która jest pętlą, liczymy ją jako dwie krawędzie.
Stopniem wierzchołka grafu skierowanego nazywamy sumę dwóch liczb – liczby krawędzi do niego wchodzących (stopień wejściowy) oraz liczby krawędzi z niego wychodzących (stopień wyjściowy).
O grafie mówimy, że jest spójny, jeśli dla każdych dwóch jego wierzchołków istnieje ścieżka, która je ze sobą łączy.
Graf nieskierowany jest spójny, jeśli dla każdej pary wierzchołków istnieje ścieżka, która je łączy. Jeśli takiej ścieżki nie ma, wówczas taki graf określamy niespójnym.
O grafie skierowanym możemy powiedzieć, że jest grafem spójnym, jeśli po tym, jak wszystkie jego krawędzie skierowane zostaną zastąpione krawędziami nieskierowanymi, graf ten będzie grafem nieskierowanym spójnym,
Więcej na temat spójności grafu skierowanego znajdziesz w dalszej części e‑materiału w punkcie Digrafy.
Zapoznaj się z przykładem grafu nieskierowanego, który nie jest spójny (składa się z trzech spójnych składowych).

Spójny podgraf takiego grafu, który nie jest zawarty w żadnym większym spójnym podgrafie, nazywamy składową grafu. Możemy zauważyć, że każdy graf niespójny jest sumą pewnych spójnych grafów.
Przyjrzyjmy się grafom z Przykładu 1. Dane są trzy grafy spójne nieskierowane. Ich suma daje graf nieskierowany niespójny.
W kontekście spójności grafów definiujemy również pojęcie mostu, czyli krawędzi, której usunięcie sprawi, że graf zwiększy liczbę spójnych składowych o jeden.

Pojęcie mostu jest podstawą działania niektórych algorytmów grafowych, takich jak na przykład algorytm Fleury'ego służący do znajdowania w grafie ścieżki lub cyklu Eulera.
Zaprezentowany graf to graf spójny, którego wierzchołki mają następujące stopnie:
stopień wierzchołka 0: 3
stopień wierzchołka 1: 2
stopień wierzchołka 2: 4
stopień wierzchołka 3: 2
stopień wierzchołka 4: 3
stopień wierzchołka 5: 2
Tym samym stopień grafu wynosi 4 (ponieważ tyle wynosi maksymalny stopień wierzchołka grafu).

Spójrzmy, jak wygląda graf przedstawiający mosty i lądy w Królewcu z czasów Eulera .

W teorii grafów taka ścieżka zamknięta nazywana jest cyklem Eulera. O ścieżce mówimy, że jest zamknięta, jeśli wierzchołek początkowy jest tożsamy z jej wierzchołkiem końcowym.
Warunki istnienia cyklu Eulera w grafie określa następujące twierdzenie:
Spójny graf zawiera cykl Eulera wtedy i tylko wtedy, gdy każdy wierzchołek jest parzystego stopnia.
Warunkiem koniecznym istnienia cyklu Eulera jest spójność grafu. Gdyby graf nie był spójny, nie istniałaby możliwość odwiedzenia wszystkich jego wierzchołków w jednym cyklu.
Digrafy
Digraf (inaczej graf skierowany) to taki graf, w którym krawędzie mają ustalony kierunek z jednego wierzchołka do drugiego. Na rysunku zwykle jest to oznaczane strzałką w jednym z końców krawędzi. Formalnie powiemy, że grafem skierowanym (digrafem) nazywamy graf składający się z niepustego i skończonego zbioru wierzchołków oraz skończonej rodziny krawędzi , czyli z uporządkowanych par elementów zbioru .
Dla zaprezentowanego grafu zbiór wierzchołków to . Rodzina krawędzi to następujące pary: .

Jeśli i są wierzchołkami, to krawędź skierowana jest parą uporządkowaną i oznacza krawędź poprowadzoną z wierzchołka do wierzchołka . Jeśli w pewnym grafie istnieją krawędzie skierowane i , to nie są one krawędziami wielokrotnymi, ponieważ tutaj uwzględniamy kolejność wierzchołków.
Poruszanie się po krawędziach wychodzących
Stopniem wyjściowym wierzchołka digrafu nazywamy liczbę krawędzi skierowanych, wychodzących z wierzchołka . Stopień wyjściowy wierzchołka oznaczamy symbolem:
Analogicznie, stopniem wejściowym wierzchołka w digrafie będzie liczba krawędzi skierowanych, poprowadzonych do wierzchołka . Liczbę taką oznaczamy symbolem:
W digrafach możemy przechodzić przez krawędzie tylko w kierunku zgodnym z kolejnością wierzchołków krawędzi. Na przykład krawędź skierowaną można przejść tylko od do , natomiast odwrotne przejście jest niemożliwe.
Dla zaprezentowanego wyżej grafu stopień wejściowy wierzchołka to 1 (do wierzchołka skierowana jest tylko jedna krawędź), natomiast stopień wyjściowy wierzchołka to 2 (z wierzchołka wychodzą dwie krawędzie).
Spójność digrafów
Ponieważ w digrafach przechodzimy po danej krawędzi w ściśle określonym kierunku, może dojść do sytuacji, że z pewnego wierzchołka nie dostaniemy się do drugiego.

Mówimy, że podgraf skierowany jest silnie spójną składową, jeśli każdy wierzchołek jest osiągalny z każdego innego wierzchołka składowej - czyli z każdego wierzchołka możemy poprowadzić ścieżkę do dowolnego wierzchołka.
Dla zaprezentowanego grafu możemy wyróżnić trzy podgrafy, które są silnie spójnymi składowymi. Otoczono je przerywanymi liniami.
Badanie stopnia wierzchołka grafu
Graf nieskierowany
Specyfikacja problemu:
Dane:
macierz_sasiedztwa– macierz sąsiedztwa grafu; lista dwuwymiarowa liczb naturalnych
Wynik:
wypisane stopnie poszczególnych wierzchołków
Dany jest następujący graf spójny nieskierowany bez wag:

Jego macierz sąsiedztwa:

Implementacja zaprezentowanej macierzy sąsiedztwa w języku Python:
Zapiszmy funkcję odpowiedzialną za określenie stopni poszczególnych wierzchołków.
Zaczniemy od zapisania nagłówka funkcji. Funkcja przyjmuje jeden argument – macierz sąsiedztwa grafu.
W kolejnym kroku tworzymy zmienną n przechowującą długość listy macierz_sasiedztwa (liczbę wierzchołków) oraz listę stopnie o długości równej liczbie wierzchołków grafu. Listę wypełniamy zerami. Będzie ona przechowywać stopnie kolejnych wierzchołków.
Zapisujemy pętlę for, która będzie iterować przez wszystkie wierzchołki (wiersze).
Zapisujemy zagnieżdżoną pętlę for, która będzie iterowała przez pozostałe wierzchołki grafu (kolumny w danym wierszu).
W pętli zapisujemy instrukcję warunkową, za pomocą której sprawdzimy, czy wierzchołki o danych indeksach są połączone krawędzią. Jeśli tak, zwiększamy stopień i-tego wierzchołka, czyli inkrementujemy wartość i-tego elementu listy stopnie.
Dodajemy kolejną instrukcję warunkową, która obsłuży przypadek, w którym krawędź jest pętlą – wtedy liczymy ją podwójnie – ponownie inkrementujemy i-ty element listy stopnie.
Kompletny kod programu:
Wynik działania programu:
Graf skierowany
Specyfikacja problemu:
Dane:
macierz_sasiedztwa– macierz sąsiedztwa grafu; lista dwuwymiarowa liczb naturalnych
Wynik:
wypisane stopnie poszczególnych wierzchołków (sumy stopni wierzchołków wejściowych i wyjściowych)
Dany jest następujący graf spójny skierowany bez wag:

Macierz sąsiedztwa grafu:

Implementacja zaprezentowanej macierzy sąsiedztwa w języku Python:
Zapiszmy funkcję odpowiedzialną za określenie stopni poszczególnych wierzchołków. W przypadku tej implementacji nie będziemy rozróżniać stopni wejściowych oraz wyjściowych. Stopień wierzchołka będzie równy sumie stopni wejściowych i wyjściowych wierzchołka.
W przypadku prezentowanego programu będziemy obliczać sumę stopni wejściowych oraz wyjściowych dla każdego wierzchołka.
Zaczniemy od zapisania nagłówka funkcji. Funkcja przyjmuje jeden argument – macierz sąsiedztwa.
Zmiennej n przypisujemy wartość równą liczbie wierzchołków.
W kolejnym kroku tworzymy listę stopnie o długości równej n. Listę wypełniamy zerami. Będzie ona przechowywać stopnie kolejnych wierzchołków.
Zapisujemy pętlę for, która będzie iterować przez wszystkie wierzchołki (wiersze).
Zapisujemy zagnieżdżoną pętlę for, która będzie iterowała przez pozostałe wierzchołki grafu (kolumny w danym wierszu) – w pętli sprawdzimy, czy istnieje krawędź między wierzchołkiem o indeksie i a j.
W pętli zapisujemy zatem instrukcję warunkową, za pomocą której sprawdzimy, czy wierzchołki o danych indeksach (i oraz j) są połączone krawędzią. Jeśli tak, zwiększamy stopnie i-tego (ponieważ ma on krawędź wychodzącą) oraz j-tego wierzchołka (ponieważ ma on krawędź wchodzącą), czyli inkrementujemy wartości i-tego oraz j‑tego elementu listy stopnie.
Stopień wierzchołka w grafie skierowanym definiujemy w tym przypadku jako sumę krawędzi wchodzących do wierzchołka i wychodzących z wierzchołka.
Zatem jeśli istnieje krawędź między wierzchołkami i oraz j, to dla wierzchołka i jest to krawędź wyjściowa, a dla wierzchołka j – wejściowa.
Kompletny kod programu:
Wynik działania programu:
Jeśli chcemy obliczać osobno stopnie wejściowe i wyjściowe, musimy zmodyfikować funkcję, by osobno obliczać liczbę obu stopni dla każdego wierzchołka. Potrzebne będą dwie listy – jedna przechowująca stopnie wyjściowe, druga – wejściowe.
Zmienimy również sposób inkrementowania zmiennych w instrukcji warunkowej oraz wypisywania wyników.
Kompletny kod programu wraz z wywołaniem funkcji:
Efekt działania programu:
Badanie stopnia grafu
Graf nieskierowany
Specyfikacja problemu:
Dane:
macierz_sasiedztwa– macierz sąsiedztwa grafu; lista dwuwymiarowa liczb naturalnych
Wynik:
stopień grafu nieskierowanego
Dany jest następujący graf spójny nieskierowany bez wag:

Macierz sąsiedztwa grafu:

Implementacja zaprezentowanej macierzy sąsiedztwa w języku Python:
W programie wykorzystamy funkcję odpowiedzialną za określenie stopni poszczególnych wierzchołków – zmodyfikujemy ją nieco, by wykorzystać listę stopnie w dalszej części programu.
Zmodyfikowana funkcja:
Dodatkowo w programie wykorzystamy jeszcze funkcję odpowiedzialną za znalezienie największego stopnia wśród stopni wierzchołków.
Zapiszmy ją. Jako argument przekażemy do funkcji listę przechowującą stopnie kolejnych wierzchołków.
Nagłówek funkcji:
Zaczniemy od utworzenia zmiennej maksymalnyStopien. Przypiszemy jej pierwszy element listy stopnie (element o indeksie 0).
Następnie zapiszemy pętlę for, która będzie iterowała przez elementy listy stopnie, zaczynając od elementu o indeksie 1.
W pętli zapisujemy instrukcję warunkową. Wykorzystamy ją do sprawdzenia, czy aktualnie analizowany stopień wierzchołka jest większy od wartości przechowywanej w zmiennej maksymalnyStopien. Jeśli tak, zaktualizujemy wartość tej zmiennej, przypisując jej wartość analizowanego stopnia wierzchołka.
Po przeiterowaniu przez elementy listy stopnie funkcja zwraca wartość zmiennej maksymalnyStopien, czyli stopień grafu.
Kompletny kod programu:
Wynik działania programu:
Graf skierowany
Specyfikacja problemu:
Dane:
macierz_sasiedztwa– macierz sąsiedztwa grafu; lista dwuwymiarowa liczb naturalnych
Wynik:
stopień grafu skierowanego
Dany jest następujący graf spójny skierowany bez wag:

Macierz sąsiedztwa grafu:

Implementacja zaprezentowanej macierzy sąsiedztwa w języku Python:
W programie ponownie wykorzystamy zmodyfikowaną funkcję odpowiedzialną za określenie stopni poszczególnych wierzchołków.
Funkcja:
Funkcja odpowiedzialna za określenie największego stopnia wierzchołka jest taka sama, jak dla implementacji dla grafu nieskierowango:
Kompletny kod programu:
Wynik działania programu:
Słownik
ścieżka zamknięta, która zaczyna się i kończy w tym samym wierzchołku
struktura składająca się z niepustego zbioru wierzchołków oraz ze zbioru krawędzi; dla grafu zbiór wierzchołków oznaczamy (ang. verticies – wierzchołki), a zbiór krawędzi – (ang. edges – krawędzie); liczbę elementów zbioru oznaczamy literą , zaś liczbę elementów zbioru literą
graf, w którym każda para wierzchołków połączona jest ścieżką
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ą)
graf, w którym możliwe jest połączenie dwóch wierzchołków za pomocą kilku krawędzi lub w którym występują krawędzie łączące wierzchołek sam ze sobą
liczba krawędzi incydentnych z danym wierzchołkiem
trasa łącząca kolejne wierzchołki grafu, w której wszystkie krawędzie są różne
inaczej: punkt, węzeł; element niepustego zbioru, który wraz ze zbiorem krawędzi tworzy graf