Grafem nazywamy strukturę G = (V, E): V zbiór węzłów lub wierzchołków, Grafy dzielimy na grafy skierowane i nieskierowane:

Podobne dokumenty
Algorytmy grafowe. Wykład 2 Przeszukiwanie grafów. Tomasz Tyksiński CDV

Struktury danych i złożoność obliczeniowa Wykład 5. Prof. dr hab. inż. Jan Magott

Wstęp do Programowania potok funkcyjny

a) 7 b) 19 c) 21 d) 34

Ogólne wiadomości o grafach

Algorytmiczna teoria grafów

Wstęp do Programowania potok funkcyjny

Przykłady grafów. Graf prosty, to graf bez pętli i bez krawędzi wielokrotnych.

Algorytmy i Struktury Danych.

Reprezentacje grafów nieskierowanych Reprezentacje grafów skierowanych. Wykład 2. Reprezentacja komputerowa grafów

Algorytmy grafowe. Wykład 1 Podstawy teorii grafów Reprezentacje grafów. Tomasz Tyksiński CDV

Kolorowanie wierzchołków Kolorowanie krawędzi Kolorowanie regionów i map. Wykład 8. Kolorowanie

Matematyka dyskretna. Andrzej Łachwa, UJ, B/14

Sortowanie topologiczne skierowanych grafów acyklicznych

Złożoność obliczeniowa klasycznych problemów grafowych

Wstęp do programowania. Drzewa. Piotr Chrząstowski-Wachtel

Wykład 10 Grafy, algorytmy grafowe

Algorytmy Równoległe i Rozproszone Część V - Model PRAM II

MATEMATYKA DYSKRETNA - MATERIAŁY DO WYKŁADU GRAFY

Matematyczne Podstawy Informatyki

Matematyczne Podstawy Informatyki

WYŻSZA SZKOŁA INFORMATYKI STOSOWANEJ I ZARZĄDZANIA

Matematyczne Podstawy Informatyki

Grafy (3): drzewa. Wykłady z matematyki dyskretnej dla informatyków i teleinformatyków. UTP Bydgoszcz

Podstawowe własności grafów. Wykład 3. Własności grafów

Matematyka dyskretna. Andrzej Łachwa, UJ, /14

TEORIA GRAFÓW I SIECI

Algorytmiczna teoria grafów

Algorytmy i Struktury Danych.

Zofia Kruczkiewicz, Algorytmu i struktury danych, Wykład 14, 1

Algorytmy i Struktury Danych.

Drzewa. Jeżeli graf G jest lasem, który ma n wierzchołków i k składowych, to G ma n k krawędzi. Własności drzew

Algorytmy z powracaniem

Graf. Definicja marca / 1

Digraf. 13 maja 2017

Siedem cudów informatyki czyli o algorytmach zdumiewajacych

Algorytmy Grafowe. dr hab. Bożena Woźna-Szcześniak, prof. UJD. Wykład 1,2,3. Uniwersytet Humanistyczno-Przyrodniczy im. Jana Długosza w Częstochowie

Matematyka dyskretna. Andrzej Łachwa, UJ, /14

Wykład 7. Algorytmy grafowe

Algorytmy równoległe. Rafał Walkowiak Politechnika Poznańska Studia inżynierskie Informatyka 2010

Wykłady z Matematyki Dyskretnej

Wstęp do programowania. Zastosowania stosów i kolejek. Piotr Chrząstowski-Wachtel

Algorytmy i Struktury Danych

Algorytmy i struktury danych. Drzewa: BST, kopce. Letnie Warsztaty Matematyczno-Informatyczne

Matematyka dyskretna. Andrzej Łachwa, UJ, /15

Temat: Struktury danych do reprezentacji grafów. Wybrane algorytmy grafowe.

Teoria grafów podstawy. Materiały pomocnicze do wykładu. wykładowca: dr Magdalena Kacprzak

Algorytmy i Struktury Danych.

Digraf o V wierzchołkach posiada V 2 krawędzi, zatem liczba różnych digrafów o V wierzchołkach wynosi 2 VxV

Matematyka Dyskretna - zadania

Wykład 8. Drzewo rozpinające (minimum spanning tree)

MATEMATYKA DYSKRETNA - KOLOKWIUM 2

Podstawy programowania 2. Temat: Drzewa binarne. Przygotował: mgr inż. Tomasz Michno

Rozwiązywanie problemów metodą przeszukiwania

Porównanie algorytmów wyszukiwania najkrótszych ścieżek międz. grafu. Daniel Golubiewski. 22 listopada Instytut Informatyki

G. Wybrane elementy teorii grafów

Egzaminy i inne zadania. Semestr II.

Programowanie obiektowe

Algorytmy i Struktury Danych

Marek Miszczyński KBO UŁ. Wybrane elementy teorii grafów 1

Programowanie obiektowe

Grafy i Zastosowania. 9: Digrafy (grafy skierowane) c Marcin Sydow

Wstęp do programowania. Listy. Piotr Chrząstowski-Wachtel

Algorytm Dijkstry znajdowania najkrótszej ścieżki w grafie

Kolorowanie wierzchołków

Drzewa spinające MST dla grafów ważonych Maksymalne drzewo spinające Drzewo Steinera. Wykład 6. Drzewa cz. II

Grafy i Zastosowania. 5: Drzewa Rozpinające. c Marcin Sydow. Drzewa rozpinające. Cykle i rozcięcia fundamentalne. Zastosowania

ĆWICZENIE NR 1 WPROWADZENIE DO INFORMATYKI

Struktury danych i złożoność obliczeniowa Wykład 7. Prof. dr hab. inż. Jan Magott

Znajdowanie skojarzeń na maszynie równoległej

Matematyka dyskretna

Algorytmy i Struktury Danych

Czy istnieje zamknięta droga spaceru przechodząca przez wszystkie mosty w Królewcu dokładnie jeden raz?

. Podstawy Programowania 2. Grafy i ich reprezentacje. Arkadiusz Chrobot. 9 czerwca 2016

Podstawy Programowania 2 Grafy i ich reprezentacje. Plan. Wstęp. Teoria grafów Graf skierowany. Notatki. Notatki. Notatki. Notatki.

Analiza algorytmów zadania podstawowe

Teoria grafów II. Materiały pomocnicze do wykładu. wykładowca: dr Magdalena Kacprzak

Kolorowanie wierzchołków grafu

1. Algorytmy przeszukiwania. Przeszukiwanie wszerz i w głąb.

Algorytmy i Struktury Danych.

Teoria grafów dla małolatów. Andrzej Przemysław Urbański Instytut Informatyki Politechnika Poznańska

. Podstawy Programowania 2. Algorytmy dfs i bfs. Arkadiusz Chrobot. 2 czerwca 2019

Algorytm DFS Wprowadzenie teoretyczne. Algorytm DFS Wprowadzenie teoretyczne. Algorytm DFS Animacja. Algorytm DFS Animacja. Notatki. Notatki.

Opracowanie prof. J. Domsta 1

Iteracje. Algorytm z iteracją to taki, w którym trzeba wielokrotnie powtarzać instrukcję, aby warunek został spełniony.

1 Wprowadzenie do algorytmiki

7. Teoria drzew - spinanie i przeszukiwanie

KURS MATEMATYKA DYSKRETNA

Grafy. Graf ( graf ogólny) to para G( V, E), gdzie:

Grafy podstawowe pojęcia

1 Automaty niedeterministyczne

Grafy co o ich rysowaniu wiedzą przedszkolaki i co z tego wynika dla matematyków

Lista 4. Kamil Matuszewski 22 marca 2016

Znajdowanie maksymalnych skojarzeń przy pomocy eliminacji Gaussa

SKOJARZENIA i ZBIORY WEWN. STABILNE WIERZCH. Skojarzeniem w grafie G nazywamy dowolny podzbiór krawędzi parami niezależnych.

Matematyka dyskretna. Andrzej Łachwa, UJ, /15

Suma dwóch grafów. Zespolenie dwóch grafów

Wydział Zarządzania AGH. Katedra Informatyki Stosowanej. Pętle. Programowanie komputerowe

6. Wstępne pojęcia teorii grafów

Transkrypt:

Wykład 4 grafy Grafem nazywamy strukturę G = (V, E): V zbiór węzłów lub wierzchołków, E zbiór krawędzi, Grafy dzielimy na grafy skierowane i nieskierowane: Formalnie, w grafach skierowanych E jest podzbiorem V x V, czyli podzbiorem zbioru par: {(x,y) x,y należą do V} Krawędzie oznaczamy strzałkami. W grafach nieskierowanych E jest podzbiorem zbioru dwu-elementowych podzbiorów V: {{x,y} x,y należą V } Krawędzie oznaczamy odcinkami.

Rys.1. Graf nieskierowany Rys.2. Graf skierowany Graf może być etykietowany elementami zbioru etykiet A. Wtedy jest trójką (V,E,M) M: E A Rozmiar grafu jest równy sumie V + E Graf nieskierowany: E ( V x V )\ 2 Graf skierowany: E V x V

Podstawowe implementacje grafu G Macierz sąsiedztwa: M[x,y] = 1 jeśli (x,y) należy do E 0 jeśli (x,y) nie należy do E Budujemy tablicę o rozmiarach V * V, gdzie V - liczba wierzchołków. Wypełniamy ją: Zerem - jeśli dwa wierzchołki nie są połączone krawędzią i Jedynką- jeśli dwa wierzchołki są połączone. Oto macierz sąsiedztwa dla grafu z rysunku 1: 1 2 3 4 5 1 0 1 1 0 1 2 1 0 1 1 1 3 1 1 0 1 0 4 0 1 1 0 1 5 1 1 0 1 0 W tej implementacji jest potrzebna pamięć O(n 2 ) dla n = V.

Lista incydencji (sąsiedztwa) Dla każdego wierzchołka x budujemy listę (oznaczaną L[x]) dla wierzchołków y połączonych krawędzią z x. Lista dla grafu z rysunku 1 wygląda następująco: 1: 2, 3, 5 2: 1, 3, 4, 5 3: 1, 2, 4 4: 2, 3, 5 5: 1,2,4 W tej implementacji jest potrzebna pamięć O( V + E ).

Macierz incydencji Tablica o rozmiarach V * E. Jeśli krawędź wychodzi z danego wierzchołka to piszemy w odpowiedniej kolumnie (-1), jeśli do niego wchodzi piszemy (+1), jeśli wierzchołek nie należy do krawędzi piszemy 0, jeśli jest to pętla własna piszemy 2. Oto przykład dla grafu z rys. 2. 1 2 3 4 5 1-2 -1 1 0 0 0 2-4 0-1 0 1 0 2-5 0-1 0 0 1 3-2 0 1-1 0 0 4-3 0 0 1-1 0 5-1 1 0 0 0-1 5-4 0 0 0 1-1 W tej implementacji jest potrzebna pamięć O( V * E ).

Dodatkowe pojęcia dla grafów Stopień wierzchołka - liczba krawędzi do niego przyległych Graf regularny - graf, w którym każdy wierzchołek ma taki sam stopień Graf planarny - graf, który można przedstawić na płaszczyźnie tak, by żadne dwie krawędzie się nie przecinały f-graf - graf z ograniczonym stopniem wierzchołka, tzn. jego stopień nie może być większy niż f. Graf prosty - to graf bez pętli własnych i krawędzi równoległych Niezmiennik grafu - to liczba lub ciąg liczb, który zależy tylko od struktury grafu a nie od sposobu jego poetykietowania (np. liczba wierzchołków, liczba krawędzi) Liczba chromatyczna grafu - najmniejsza liczba kolorów do pokolorowania tak, by żadne dwa przyległe wierzchołki nie były tego samego koloru.

stopień wierzchołka 1 =2, wierzchołka 2 =3, graf planarny, f-graf dla f=3 graf 2-regularny, planarny graf planarny, f-graf dla f=4 graf planarny, liczba chromatyczna wynosi 3

Algorytm przechodzenia (przeszukiwania) grafu Wychodząc od wierzchołka p, należy odwiedzić każdy wierzchołek i każdą krawędź, które są osiągalne z p. Dozwolonym ruchem jest przejście krawędzią grafu wychodzącą z odwiedzonego już wierzchołka. W jednym kroku będziemy odwiedzać jeden z wierzchołków oraz jedną z krawędzi grafu i zaznaczać je jako odwiedzone. Na początku wszystkie wierzchołki i wszystkie krawędzie są zaznaczone jako nie odwiedzone.

1. Odwiedź wierzchołek p i zaznacz go jako odwiedzony. 2. Dopóki z jednego z odwiedzonych wierzchołków wychodzi nie odwiedzona jeszcze krawędź, wykonuj podane czynności: a) wybierz odwiedzony wierzchołek, powiedzmy v, z którego wychodzi nie odwiedzona krawędź; b) wybierz nie odwiedzoną krawędź, powiedzmy (v, w), wychodzącą z wierzchołka v; c) zaznacz krawędź (v, w) jako odwiedzoną; d) jeśli wierzchołek w nie został odwiedzony, odwiedź go i zaznacz jako odwiedzony. Formalnie można pokazać, że powyższy algorytm jest poprawny. Nie biorąc pod uwagę samej procedury odwiedzania wierzchołków i krawędzi złożoność algorytmu jest rzędu O( V + E )

Aby otrzymać konkretny algorytm należy wykonać podane tu kroki. 1. Przyjąć odpowiednią reprezentację grafu, na przykład V = {1. 2... n} i listy sąsiedztwa L[v] dla v należącego do V. 2. Określić co to znaczy "zaznacz wierzchołek jako odwiedzony". Można na przykład dołączyć do każdego wierzchołka v pole visited[v] i przyjąć, że false oznacza wierzchołek nie odwiedzony", a true "wierzchołek odwiedzony". 3. Określić sposób wyboru odwiedzanego wierzchołka, z którego wychodzi nie odwiedzona krawędź. Można na przykład przechowywać takie wierzchołki w kolejce lub na stosie 4. Określić sposób odróżniania (dla danego wierzchołka) krawędzi odwiedzonych od nie odwiedzonych. Można na przykład trzymać na liście sąsiedztwa danego wierzchołka v wskaźnik current[v] do pierwszej nie odwiedzonej krawędzi (current[v] = nil oznacza, że wszystkie krawędzie wychodzące z danego wierzchołka zostały odwiedzone).

Bardziej uszczegółowiony schemat przechodzenia grafu (visit jest procedurą "odwiedzania" wierzchołka; nie ma procedury odwiedzania krawędzi). for v := 1 to n do visited[v] := false; ustaw wskaźnik current[v] na pierwszy wierzchołek na liście L[v] for v := 1 to n do if visited[v] = false then przeszukaj(v); przeszukaj(p); visit(p); visited[p] := true; if current[p] <> nil then S := {p}; while S <> 0 do {S zawiera wszystkie odwiedzone do tej pory wierzchołki, z których wychodzą nie odwiedzone jeszcze krawędzie} wybierz wierzchołek v ze zbioru S; niech w będzie wierzchołkiem wskazywanym przez current[v]; przesuń current[v] do następnego wierzchołka na liście L[v]; if current[v] = nil then S := S - {v}; if not visited[w] then visit(w); visited[w] := true; if current[w] <> nil then S := S u {w} end end Przyjęte implementacje zbioru S to stos i kolejka.

Najpierw uszczegółowimy schemat przechodzenia grafu, przedstawiając S za pomocą stosu i interpretując operacje na S jako operacje na stosie. Przyjmujemy, że operacje pop i push będą realizowane jako procedury, a front jako funkcja. Otrzymujemy algorytm przechodzenia grafu w głąb (metoda DFS). for v := 1 to n do visited[v] := false; ustaw wskaźnik current[v] na pierwszy wierzchołek na liście L[v] for v := 1 to n do if visited[v] = false then dfs(v); procedure dfs(p); visit(p); visited[p] := true; if current[p] <> nil then S := [ ]; push(s,p); while S <> 0 do {stos S zawiera wszystkie odwiedzone do tej pory wierzchołki, z których wychodzą nie odwiedzone jeszcze krawędzie} v := front(s); niech w będzie wierzchołkiem wskazywanym przez current[v]; przesuń current[v] do następnego wierzchołka na liście L[v]; if current[v] = nil then pop(s); if not visited[w] then visit(w); visited[w] := true; if current[w] <> nil then push(s,w) end end

Zapiszemy teraz schemat przechodzenia grafu, przedstawiając S jako kolejkę i interpretując operacje na S jako operacje na kolejce. (Przyjmujemy, że operacje pop i inject są realizowane jako procedury, a front jako funkcja). Algorytm przechodzenia grafu wszerz (metoda BFS) for v := 1 to n do visited[v] := false; ustaw wskaźnik current[v] na pierwszy wierzchołek na liście L[v] for v := 1 to n do if visited[v] = false then bfs(v); procedure bfs(p); visit(p); visited[p] := true; if current[p] <> nil then S := [ ]; inject(s,p); while S <> 0 do {kolejka S zawiera wszystkie odwiedzone do tej pory wierzchołki, z których wychodzą nie odwiedzone jeszcze krawędzie} v := front(s); niech w będzie wierzchołkiem wskazywanym przez current[v]; przesuń current[v] do następnego wierzchołka na liście L[v]; if current[v] = nil then pop(s); if not visited[w] then visit(w); visited[w] := true; if current[w] <> nil then inject(s,w) end end

DFS z czasami odwiedzenia d[] i przetworzenia f[] for v := 1 to n do visited[v] := false; ustaw wskaźnik current[v] na pierwszy wierzchołek na liście L[v] for v := 1 to n do if visited[v] = false then dfs(v); procedure dfs(p); t := 0; visit(p); visited[p] := true; t := 1; d[p] := t; if current[p] = nil then t := 2; f[p] := t if current[p] <> nil then S := [ ]; push(s,p); while S <> 0 do {stos S zawiera wszystkie odwiedzone do tej pory wierzchołki, z których wychodzą nie odwiedzone jeszcze krawędzie} v := front(s); niech w będzie wierzchołkiem wskazywanym przez current[v]; przesuń current[v] do następnego wierzchołka na liście L[v]; if current[v] = nil then pop(s); t := t+1; f[v] := t if not visited[w] then visit(w); visited[w] := true; t := t+1; d[w] := t; if current[w] <> nil then push(s,w) else t := t+1; f[v] := t end end

Silnie spójne składowe Maksymalny podgraf G danego grafu taki, że dla każdej pary wierzchołków istnieje droga w G nazywamy silnie spójną składową G. Transpozycja grafu Dany graf G = (V,E) Graf transponowany G T = (V,E ), gdzie (x,y) należy do E wtedy i tylko wtedy (y,x) należy do E. Dla reprezentacji listowej algorytm obliczający G T ma złożoność O( V + E ). FAKT: Każda silnie spójna składowa grafu G jest po transpozycji silnie spójną składową grafu G T.

Algorytm znajdowania SSS: 1. wykonaj dfs(g) w celu przypisania każdemu wierzchołkowi czasu przetworzenia f[u], 2. oblicz G T 3. wykonaj dfs(g T ), ale w głównej pętli procedury dfs rozważaj wierzchołki w kolejności malejących wartości f[u], 4. wypisz wierzchołki z każdego drzewa w lesie przeszukiwania w głąb z kroku 3 jako oddzielną silnie spójną składową. Złożoność obliczeniowa procedury SSS(G) wynosi O( V + E ). Główna pętla: for v := 1 to n do visited[v] := false; ustaw wskaźnik current[v] na pierwszy wierzchołek na liście L[v] for v := 1 to n do if visited[v] = false then dfs(v);