RKI Zajęcia 13 Przeszukiwanie grafu wszerz
|
|
- Robert Łuczak
- 7 lat temu
- Przeglądów:
Transkrypt
1 RKI Zajęcia 13 Przeszukiwanie grafu wszerz Piersa Jarosław Wprowadzenie Biega, krzyczy pan Hilary: Gdzie są moje okulary? Szuka w spodniach i w surducie, W prawym bucie, w lewym bucie. Julian Tuwim Pan Hilary swoich okularów szukał osobiście. Na dzisiejszej lekcji zastanowimy się jak wykorzystać do szukania komputer. Wymagania wstępne: grafy, sposoby reprezentowania grafu, kolejka. 2 Czego można w grafie szukać 2.1 Problem Przypomnijmy, że graf składa się z wierzchołków połączonych krawędziami. Wierzchołki mogą być zarówno bytami abstrakcyjnymi jak liczby, ale również i bytami jak najbardziej realnymi. W naszym przykładzie będą to pomieszczenia w domu Pana Hilarego. Pamiętajmy, że krawędzie w grafie określają możliwość bezpośredniego przejścia pomiędzy przeszukiwanymi obszarami. Wierzchołki połączone krawędzią będziemy dalej nazywać sąsiednimi. Sąsiedztwo wierzchołków jest informacją, którą należy uwzględnić przeszukując graf. Informuje, że np. po sprawdzeniu kuchni Pan Hilary może się skierować na przykład do przedpokoju. Będziemy w tej lekcji zakładać, że graf jest nieskierowany, czyli krawędzie (możliwości przejścia) są symetryczne. Jeżeli zatem z kuchni można się skierować do wspomnianego przedpokoju, to zawsze można i z przedpokoju wrócić do kuchni. Pan Hilary musi skądś rozpocząć poszukiwania prawdopodobnie z kuchni, gdzie chciał poczytać gazetę przy porannej kawie. Jeżeli może się udać w dwa różne miejsca, musi wybrać jedno z nich, ale również pamiętać by zajrzeć i do tego drugiego. Przykładowo z kuchni może iść do przedpokoju albo do sypialni. Pan Hilary wybrał przedpokój, ale po jego sprawdzeniu musi pamiętać by wrócić do sypialni. Sytuacja się komplikuje gdy z przedpokoju może iść również do biblioteczki. Pan Hilary zdecydował się sprawdzać pokoje w kolejności od tych sąsiadujących z kuchnią. Kolejność tę musi zapisywać na swojej podręcznej liście (jak ją odczytał bez okularów?). Ostatnią ważną obserwacją jest by nie szukać dwa razy w tym samym miejscu. 2.2 Algorytm Przetłumaczmy problem na język grafów. Dane mamy: graf, którego wierzchołki reprezentują pomieszczenia w domu, a krawędzie możliwości przejścia między tymi pomieszczeniami, wierzchołek, który chcemy znaleźć w grafie, w naszym przykładzie pokój, w którym zostawione są okulary, 1
2 Rysunek 1: Graf pomieszczeń w domu Pana Hilarego. wierzchołek, od którego rozpoczynamy szukanie. Potrzebna nam będzie tablica o rozmiarze równym liczbie wierzchołków w grafie, w której możemy oznaczyć wierzchołki jako odwiedzone lub nieodwiedzone. Na początku wszystkie są nieodwiedzone, wraz z postępem algorytmu będziemy je odwiedzać i oznaczać, tak aby uniknąć wielokrotnego sprawdzania jednego wierzchołka. Dodatkowo będzie nam potrzebna kolejka, służąca do przechowywania wierzchołków, które oczekują na sprawdzenie. Na początku oczekuje tylko wierzchołek startowy, zatem wstawiamy go do kolejki i jednocześnie oznaczamy jako odwiedzony. Następnie powtarzamy następujące kroki tak długo jak w kolejce będą oczekujące wierzchołki: zdejmujemy wierzchołek z czoła kolejki, jeżeli jest tym szukanym, to znaleźliśmy i możemy zakończyć poszukiwania, jeżeli nie, to dla każdego sąsiada sprawdzamy czy tenże sąsiad był już odwiedzony, jeżeli nie był, to oznaczamy go jako odwiedzonego, by więcej do niego nie wracać i dodajemy do kolejki. Jeżeli w kolejce nie ma więcej elementów, to oznacza to, że przeszukaliśmy cały fragment grafu, jaki jest osiągalny z wierzchołka startowego. Jeżeli do tego czasu nie znaleźliśmy wierzchołka szukanego to, nie da się do niego dotrzeć. Ponieważ komputer lepiej radzi sobie z zapamiętywaniem liczb niż okularów, w algorytmie będziemy szukać zmiennych typu int (na przykład 8). Poniżej podany jest zapis algorytmu w pseudokodzie: // dane: int start; int szukanyelement; bool czyjuzodwiedzony[n] = {false,..., false}; kolejka = pustakolejka(); czyjuzodwiedzony[start] = true; kolejka.push_back(start); while (kolejka.empty() == false){ int w = kolejka.front(); kolejka.zdejmijpierwszyelement() if (w == szukanyelement){ kolejka.clear(); return "znalazlem"; } // if 2
3 for (int v = sasiedziwezla(w)){ if (czyjuzodwiedzony[v] == false){ czyjuzodwiedzony[v] = true; kolejka.push_back(v); } // if } // for v } // while return "nie znalazlem"; 2.3 Wyszukiwanie najkrótszej drogi Zauważmy jeszcze jedną bardzo ważną właściwość tego algorytmu. Algorytm BSF zawsze dochodzi do wierzchołka najkrtótszą (tj. liczącą najmniej krawędzi) drogą, o ile istnieje jakakolwiek droga. Aby tę drogę odtworzyć należy dla każdego wierzchołka, za wyjątkiem startowego, zapamiętać jego rodzica, z którego do wierzchołka doszliśmy. Będzie nam do tego potrzebna tablica. Posłuży nam ona również do oznaczania wierzchołków nieodwiedzonych (w kodzie jest to wartość 1). Wierzchołek startowy rodzica nie ma jest początkiem wszystkich ścieżek, dlatego też rezerwujemy dla niego dodatkowe oznaczenie (u nas 10). Wierzchołki są numerowane liczbami od 0 do n 1 więc oznaczenia nie będą kolidowały. Każde inne oznaczenia, które nie wprowadzają kolizji, będą równie dobre. Aby odtworzyć drogę należy, po przeszukaniu grafu wybrać krawędź pomiędzy wierzchołkiem szukanym a jego rodzicem, następnie pomiędzy tymże rodzicem a rodzicem rodzica itd. aż dojdziemy do wierzchołka startowego Tym sposobem jesteśmy w stanie zbudować drzewo najkrótszych dróg wychodzących z wierzchołka startowego. Określa się je również mianem drzewa osiągalności lub drzewa BFS. Zapis algorytmu w pseudokodzie: // dane: int start; int szukanyelement; // rodzice // tablica służy nam również do pamiętania czy wierzchołek został odwiedzony // w tym przypadku -1 oznacza, że nie został int rodzice[n] = {-1,..., -1}; kolejka = pustakolejka(); // oznaczamy wierzchołek startowy, musimy przypisać wartość, która nie jest // numerem żadnego wierzchołka, ani oznaczeniem "nieodwiedzony" czyjuzodwiedzony[start] = -10; kolejka.push_back(start); while (kolejka.empty() == false){ int w = kolejka.front(); kolejka.zdejmijpierwszyelement() for (int v = sasiedziwezla(w)){ // wierzchołek v jeszcze nie był odwiedzony if ( rodzice[v] == -1){ // przypisujemy wierzchołkowi v jego rodzica - w czyjuzodwiedzony[v] = w; kolejka.push_back(v); } // if } // for v } // while // odczytywanie ścieżki if (rodzice[szukanyelement] == -1){ return "nie znalazlem"; 3
4 } else { int wezel = szukanyelement; int rodzic = rodzice[szukanyelement]; // dopóki nie dojdziemy do korzenia while (rodzic!= -10){ std::cout << "(" << wezel << " " << rodzic << ")\n"; // przechodzimy o jeden krok w górę ścieżki; wezel = rodzic; rodzic = rodzice[wezel]; } // while return "znalazlem"; } // if... else Uwaga. W tym punkcie jako najkrótszą drogę rozumiemy tę, która liczy najmniej krawędzi. W lekcji 15. poznamy inny sposób definiowania odległości pomiędzy wierzchołkami w grafie, który będzie wymagał innego algorytmu. 2.4 Analiza złożoności Oznaczmy liczbę wierzchołków w grafie przez n oraz liczbę krawędzi przez m. Algorytm na pierwszy rzut oka może wyglądać kosztownie, ze względu na złożoność czasową, gdyż ma pętlę for zagnieżdżoną wewnątrz while. Zauważmy jednak, że w każdym kroku z kolejki zdejmujemy jeden element. Z drugiej strony każdy z elementów dodajemy co najwyżej jeden raz, a nie możemy go zdjąć z kolejki jeżeli nie został wcześniej dodany. Co za tym idzie sumaryczna liczba dodawań (i analogicznie zdejmowań) z kolejki nie przekracza liczby wierzchołków w grafie czyli n. Nieco gorzej jest ze sprawdzaniem czy wierzchołek był już odwiedzony. Na złożoność okazuje się mieć wpływ wykorzystany sposób reprezentacji grafu. Dla list sąsiedztwa. Dla każdego wierzchołka trzeba sprawdzić wszystkich jego sąsiadów. Wierzchołek ma tylu sąsiadów, ile krawędzi z niego wychodzi. Każda krawędź łączy dwa wierzchołki, a każdy wierzchołek jest sprawdzany (co najwyżej) raz. Co za tym idzie, liczba sprawdzań nie przekracza liczby krawędzi w grafie przemnożonej przez 2. Otrzymujemy zatem algorytm o złożoności O(n + m). Dla macierzy sąsiedztwa. Sprawdzenie wszystkich sąsiadów zawsze wymaga sprawdzenia całego wiersza macierzy, który ma długość n, a w pesymistycznej sytuacji sprawdzamy dla każdego z n wierzchołków. Oznacza to, że złożoność obliczeniowa wyniesie O(n 2 ). Złożoność pamięciowa. Algorytm wymaga tablicy pomocniczej rozmiaru n oraz kolejki. W kolejce przetrzymywane są wierzchołki, przy czym jeden wierzchołki co najwyżej jeden raz, a zatem liczba elementów w kolejce nie przekroczy n. Złożoność pamięciowa wynosi zatem O(n). Uwaga: w tej analizie nie bierzemy pod uwagę rozmiaru danych wejściowych. Lista krawędzi oraz dwie tablice zajmują O(n + m) pamięci, a macierz sąsiedztwa O(n 2 ). 3 Ćwiczenie Napisz program, który wczytuje kolejno: n liczbę wierzchołków w grafie, m liczbę krawędzi w grafie, m par liczb a b rozdzielonych spacjami, reprezentujących krawędzie w grafie, w którym wierzchołki są numerowane od 0 do n 1 włącznie, x szukany wierzchołek w grafie, s wierzchołek grafu, od którego należy rozpocząć poszukiwanie. 4
5 Jako wynik program powinien wypisać: TAK, jeżeli da się znaleźć x startując z s i NIE w przeciwnym wypadku. Wskazówki: 1. W lekcji 12 były omawiane metody reprezentowania grafu, rekomendowane to: dwie tablice, listy sąsiedztwa. 2. Tablice w C++ oraz Javie są indeksowane od zera, wykorzystaj to do wygodnej reprezentacji grafu. Wbrew pozorom jest to znaczne ułatwienie. 3. Skorzystaj z dostępnych struktur w bibliotece standardowej C++ / Javy. Porównaj czas działania algorytmu gdy graf jest reprezentowany przez macierz sąsiedztwa, z czasem uzyskanym dla list sąsiedztwa. 3.1 Rozwiązanie dla C++: #include <iostream > #include <vector > #include <queue> int n ; std : : vector <vector <int> > s a s i e d z i ; std : : queue<int> k o l e j k a ; void wyczysc ( ) ; int main ( int argc, char argv ) { std : : c i n >> n ; // tworzymy p u s t e l i s t y sasiadow vector <int> v ; s a s i e d z i. push back ( v ) ; int m; std : : c i n >> m; // wczytujemy krawedzie for ( int i =0; i <m; i ++){ int a, b ; std : : c i n >> a >> b ; s a s i e d z i. at ( a ). push back ( b ) ; s a s i e d z i. at ( b ). push back ( a ) ; int szukany ; std : : c i n >> szukany ; int s t a r t ; std : : c i n >> s t a r t ; // t a b l i c a pomocnicza bool czyodwiedzony [ n ] ; czyodwiedzony [ i ] = f a l s e ; // algorytm BSF // dodajemy do k o l e j k i s t a r t o w y element czyodwiedzony [ s t a r t ] = true ; k o l e j k a. push ( s t a r t ) ; // dopoki w k o l e j c e s j a k i e k o l w i e k elementy while ( k o l e j k a. empty ( ) == f a l s e ){ // zdejmujemy element z k o l e j k i int wezel = k o l e j k a. f r o n t ( ) ; k o l e j k a. pop ( ) ; 5
6 // j e z e l i j e s t to ten szukany... i f ( wezel == szukany ){ std : : cout << TAK\n ; wyczysc ( ) ; return 0 ; // d l a kazdego s a s i a d a for ( int i =0; i < s a s i e d z i. at ( wezel ). s i z e ( ) ; i ++){ int s a s i a d = s a s i e d z i. at ( wezel ). at ( i ) ; // j e z e l i s a s i a d nie b y l odwiedzony to wrzucamy go do k o l e j k i i f ( czyodwiedzony [ s a s i a d ] == f a l s e ){ czyodwiedzony [ s a s i a d ] = true ; k o l e j k a. push ( s a s i a d ) ; } // w h i l e std : : cout << NIE\n ; wyczysc ( ) ; return 0 ; } // main ( ) void wyczysc ( ) { // c z y s z c z e n i e g r a f u for ( int i =0; i < s a s i e d z i. s i z e ( ) ; i ++){ s a s i e d z i. at ( i ). c l e a r ( ) ; s a s i e d z i. c l e a r ( ) ; // c z y s z c z e n i e k o l e j k i while ( k o l e j k a. empty ( )!= f a l s e ){ k o l e j k a. pop ( ) ; } // w h i l e } // wyczysc ( ) 3.2 Rozwiązanie w Javie import java. u t i l. Scanner ; import java. u t i l. Vector ; import java. u t i l. ArrayDeque ; public class RKI BSF { public s t a t i c void main ( S t r i n g [ ] a r g s ) { Scanner s = new Scanner ( System. i n ) ; // wczytujemy i l o s c wezlow i krawedzi int n = s. n e x t I n t ( ) ; int m = s. n e x t I n t ( ) ; Vector<Vector<I n t e g e r >> krawedzie = new Vector<Vector<I n t e g e r >>(); // tworzymy p u s t e l i s t y sasiadow Vector<I n t e g e r > v = new Vector<I n t e g e r >(); krawedzie. add ( v ) ; // dodajemy sasiadow for ( int i =0; i <m; i ++){ int a = s. n e x t I n t ( ) ; int b = s. n e x t I n t ( ) ; krawedzie. get ( a ). add ( b ) ; krawedzie. get ( b ). add ( a ) ; int szukany = s. n e x t I n t ( ) ; int startowy = s. n e x t I n t ( ) ; // algorytm BSF: // i n i c j a l i z u j e m y t a b l i c e pomocnicza boolean czyodwiedzony [ ] = new boolean [ n ] ; 6
7 czyodwiedzony [ i ] = f a l s e ; // tworzymy k o l e j k e, dodajemy p i e r w s z y w i e s z c h o l e k ArrayDeque<I n t e g e r > k o l e j k a = new ArrayDeque<I n t e g e r >(); k o l e j k a. addlast ( startowy ) ; czyodwiedzony [ startowy ] = true ; boolean odpowiedz = f a l s e ; // dopoki k o l e j k a j e s t n i e p u s t a while ( k o l e j k a. s i z e ( ) > 0){ // zdejmujemy element z k o l e j k i int w i e r z c h o l e k = k o l e j k a. removefirst ( ) ; // j e s l i to ten szukany... i f ( w i e r z c h o l e k == szukany ){ odpowiedz = true ; k o l e j k a. c l e a r ( ) ; break ; // dodajemy sasiadow do k o l e j k i for ( int i =0; i < krawedzie. get ( w i e r z c h o l e k ). s i z e ( ) ; i ++){ // j e z e l i s a s i a d nie b y l odwiedzony // to wrzucamy go do k o l e j k i int s a s i a d = krawedzie. get ( w i e r z c h o l e k ). get ( i ) ; i f ( czyodwiedzony [ s a s i a d ] == f a l s e ){ czyodwiedzony [ s a s i a d ] = true ; k o l e j k a. add ( s a s i a d ) ; } // w h i l e System. out. format ( %s \n, odpowiedz? TAK : NIE ) ; } // main } // c l a s s 4 Uwagi do rozwiązań W programie skorzystaliśmy z bibliotek standardowych do pracy z kolejką oraz wektorem. Kolejka była omawiana w lekcji 11. Wektor był wprowadzony w lekcji 10. Zachęcamy do zapoznania się z treścią obu lekcji przed kontynuowaniem czytania. 4.1 Uwagi do rozwiązania w C++ Rozpoczniemy od omówienia kolejki. Abyśmy mogli użyć jej w programie musimy dołączyć plik nagłówkowy. #include <queue> Następnie deklarujemy zmienną typu kolejkowego o identyfikatorze kolejka. W nawiasach trójkątnych podajemy typ danych jaki kolejka ma przechowywać u nas jest to typ całkowitoliczbowy int. std : : queue<int> k o l e j k a ; Przypomnijmy, że std:: jest standardową przestrzenią nazw, w której można znaleźć kolejkę (to samo będzie się tyczyło wektora). Aby korzystać z krótkiej formy zapisu (po prostu queue) należy na początku programu określić wykorzystywaną przestrzeń nazw: using namespace std ; Teraz kolejka jest gotowa do pracy. Możemy: dodawać element do kolejki: k o l e j k a. push ( element ) ; odczytywać element z kolejki: int element = k o l e j k a. f r o n t ( ) ; 7
8 zdejmować element z kolejki: k o l e j k a. pop ( ) ; sprawdzać czy kolejka jest pusta: i f ( k o l e j k a. empty ( ) == f a l s e ) {... } Do reprezentacji krawędzi w grafie wykorzystaliśmy bibliotekę std::vector. Należy o niej myśleć jak o dynamicznej tablicy. Struktura ta umożliwia dostęp do dowolnego elementu, a nie tylko do pierwszego jak w kolejce. Wymaga ona załączenia pliku nagłówkowego #include <vector > Następnie możemy zainicjalizować zmienną typu wektorowego, która będzie przechowywała zmienne całkowitoliczbowe int vector <int> v ; Do reprezentacji krawędzi w grafie wykorzystaliśmy natomiast wektor, który przechowuje wektory, które z kolei przechowują liczby całkowite. Główny wektor przechowuje listy sąsiadów dla każdego z wierzchołków. Należy o tym myśleć jak o tablicy tablic. std : : vector <vector <int> > s a s i e d z i ; Na wektorze możemy wykonywać następujące operacje: dodawać elementy na koniec: wektor. push back ( element ) odczytywać elementy z dowolnej pozycji int a = wektor. at ( pozycja ) Wektor sasiedzi zawiera wektory więc zwracany element jest wektorem i z niego dalej można odczytać elementy. Wykorzystaliśmy to przy szukaniu sąsiadów: int s a s i a d = s a s i e d z i. at ( i ). at ( j ) ; Złożenie takie należy rozumieć jako dostęp do j-ego elementu w i-tym wektorze. grafowych: dostęp do j-tego sąsiada wierzchołka o numerze i. możemy odczytywać liczbę elementów w wektorze int a = wektor. s i z e ( ) ; W terminach wyczyścić zawartość wektora: wektor. c l e a r ( ) ; Powyższa lista nie jest kompletna, ale na chwilę obecną powinna być wystarczająca. 4.2 Uwagi do rozwiązania w Javie W programie skorzystaliśmy z narzędzi dostępnych w bibliotece standardowej Javy. Niektóre z nich były już wprowadzone w lekcji 10 lub 11. Kolejka jest reprezentowana poprzez klasę ArrayDeque. Tego rodzaju typy danych w Javie określa się mianem klas i będziemy trzymać się tego terminu. Aby z niej skorzystać wpierw musimy ją zaimportować: import java. u t i l. ArrayDeque ; Następnie deklarowany i inicjalizowany jest obiekt tej klasy. W nawiasach trójkątnych podany jest typ jaki ma nasza kolejka przechowywać w naszym przypadku są to zmienne całkowitoliczbowe. ArrayDeque<I n t e g e r > k o l e j k a = new ArrayDeque<I n t e g e r >(); Kolejka jest gotowa do pracy: możemy dodawać element na koniec kolejki: k o l e j k a. addlast ( a ) ; 8
9 możemy zdejmować elementy z początku kolejki: int a = k o l e j k a. removefirst ( ) ; możemy podejrzeć pierwszy element bez jego zdejmowania: int a = k o l e j k a. g e t F i r s t możemy sprawdzić ile elementów liczy kolejka: int a = k o l e j k a. s i z e ( ) możemy wyczyścić całą zawartość kolejki k o l e j k a. c l e a r ( ) ; Skorzystaliśmy również z klasy Vector. Wpierw musimy ją zaimportować: import java. u t i l. Vector ; Teraz możemy zadeklarować i zainicjować obiekt klasy Vector: Vector<I n t e g e r > v = new Vector<I n t e g e r >(); Jak wyżej w nawiasach trójkątnych informujemy co wektor ma przechowywać. Krawędzie reprezentujemy jako wektor wektorów, które przechowują zmiene całkowitoliczbowe. Główny wektor przechowuje listy sąsiadów dla każdego z wierzchołków. Vector<Vector<I n t e g e r >> krawedzie = new Vector<Vector<I n t e g e r >>(); Wektor oferuje dostęp do dowolnego z elementów, a nie tylko do pierwszego jak ArrayDeque. Niektóre z dostępnych operacji: Dodanie elementu na koniec: krawedzie. add ( v ) ; Wektor umożliwia również dodawanie elementów na dowolnej pozycji, ale zajmuje to nieco więcej czasu. Odczytanie elementu na określonej i-tej pozycji int a = v. get ( i ) ; Ponieważ nasza struktura to wektor wektorów więc krawedzie. get ( i ) ; zwróci obiekt klasy Vector<Integer>, z którego dalej możemy odczytywać elementy. Wykorzystaliśmy to przy odczytywaniu krawędzi int s a s i a d = krawedzie. get ( i ). get ( j ) ; Złożenie takie należy rozumieć jako dostęp do j-ego elementu w i-tym wektorze. grafowych: dostęp do j-tego sąsiada wierzchołka o numerze i. możemy odczytywać liczbę elementów w wektorze int a = v. s i z e ( ) ; W terminach Istnieją również inne operacje, ale nie będą nam na razie potrzebne. 5 Spójność grafu 5.1 Spójność grafu Po znalezieniu okularów Pan Hilary może wreszcie udać się na mecz piłki nożnej z przyjaciółmi. Jako kapitan drużyny ma przywilej ustalenia terminu meczu. Ustalił termin na godzinę 14. Teraz musi poinformować resztę zawodników. Niestety ma numery telefonów tylko do niektórych z nich. Pan Hilary wysyła wiadomość wszystkim graczom, do których zna numer i prosi o przekazanie informacji dalej. Osoba, która otrzymała wiadomość, wysyła ją do wszystkich osób, do których ma numer (z wyjątkiem tej, od której wiadomość odebrała). Czy wystarczy to do poinformowania o meczu wszystkich zawodników? Problem daje się sprowadzić do rozważań na grafach: 9
10 Rysunek 2: Graf spójny (po lewej) i niespójny (po prawej). wierzchołkami w tym grafie będą zawodnicy, krawędź między zawodnikami oznacza, że nawzajem znają swoje numery telefonów. Algorytm rozgłaszania wiadomości o terminie meczu jest niewielką modyfikacją przeszukiwania grafu. Okazuje się, że wszyscy zostaną poinformowani jeżeli graf jest spójny. Graf jest spójny, jeżeli z każdego wierzchołka da się dojść do wszystkich pozostałych. W przeciwnym wypadku graf jest określany jako niespójny, tj. jeżeli istnieją w nim wierzchołki takie, że nie da się z jednego dojść do drugiego. Grafy niespójne bywają kłopotliwe w pracy i wiele bardziej zaawansowanych algorytmów zakłada spójność, którą trzeba sprawdzić przed dalszymi obliczeniami. Korzystając z algorytmu przeszukiwania grafu możemy szybko sprawdzić czy graf jest spójny. Pierwszy pomysł, to sprawdzić dla każdej pary wierzchołków, czy da się dojść z pierwszego do drugiego. Pomysł jest skuteczny, ale niezbyt efektywny ze względu na wielokrotne ( n2 n 2 razy) uruchamianie algorytmu. Można problem rozwiązać bardziej finezyjnie. Wystarczy przeszukiwać graf bez szukania konkretnego wierzchołka, aż do wyczerpania elementów w kolejce. A po zakończeniu pętli sprawdzić, czy każdy wierzchołek został oznaczony jako odwiedzony. Jeżeli jakikolwiek pozostał nieodwiedzony to oznacza, że nie istnieje ścieżka między nim a wierzchołkiem startowym czyli graf jest niespójny. 5.2 Zapis algorytmu w pseudokodzie bool czyjuzodwiedzony[n] = {false,..., false}; int start = dowolnywierzchołek; kolejka = pustakolejka(); czyjuzodwiedzony[start] = true; kolejka.push_back(start); while (kolejka.empty() == false){ int w = kolejka.front(); kolejka.zdejmijpierwszyelement(); for (int v = sasiedziwezla(w)){ if (czyjuzodwiedzony[v] == false){ czyjuzodwiedzony[v] = true; kolejka.push_back(v); } // if } // for v } // while if (czyjuzodwiedzony == {true,..., true}){ return "graf jest spojny"; } else { return "graf jest niespojny"; } // if 10
11 6 Ćwiczenie spójność grafu Napisz program, który wczyta kolejno: n liczbę zawodników, m liczbę znanych połączeń między zawodnikami, m kolejnych par liczb a i b, które oznaczają, że osoby a i b znają nawzajem swoje numery telefonów. Uwaga: zawodnicy są numerowani od 0 do n 1 włącznie. Następnie powinien sprawdzić czy wiadomość o meczu, wysłana przez kapitana drużyny (oznaczonego jako osoba 0) i dalej rozsyłana przez zawodników, dotrze do wszystkich zainteresowanych. Program powinien wypisać TAK gdy wszyscy zostaną poinformowani lub NIE, jeżeli przynajmniej jedna osoba nie zostanie. Przykładowe dane: TAK NIE Odpowiedź: Przykładowe dane: Odpowiedź: 6.1 Rozwiązanie w C++ #include <iostream > #include <vector > #include <queue> int n ; std : : vector <std : : vector <int> > s a s i e d z i ; std : : queue<int> k o l e j k a ; int main ( int argc, char argv ) { std : : c i n >> n ; // tworzymy g r a f std : : vector <int> v ; s a s i e d z i. push back ( v ) ; int m; std : : c i n >> m; // wczytujemy krawedzie for ( int i =0; i <m; i ++){ int a, b ; std : : c i n >> a >> b ; s a s i e d z i. at ( a ). push back ( b ) ; s a s i e d z i. at ( b ). push back ( a ) ; 11
12 // t a b l i c a pomocnicza bool czyodwiedzony [ n ] ; czyodwiedzony [ i ] = f a l s e ; // BSF int s t a r t = 0 ; czyodwiedzony [ s t a r t ] = true ; k o l e j k a. push ( s t a r t ) ; while ( k o l e j k a. empty ( ) == f a l s e ){ int wezel = k o l e j k a. f r o n t ( ) ; k o l e j k a. pop ( ) ; // d l a kazdego s a s i a d a for ( int i =0; i < ( int ) s a s i e d z i. at ( wezel ). s i z e ( ) ; i ++){ int s a s i a d = s a s i e d z i. at ( wezel ). at ( i ) ; // j e z e l i s a s i a d nie b y l odwiedzony to wrzucamy go do k o l e j k i i f ( czyodwiedzony [ s a s i a d ] == f a l s e ){ czyodwiedzony [ s a s i a d ] = true ; k o l e j k a. push ( s a s i a d ) ; } // w h i l e // j e z e l i w s z y s t k i e sa odwiedzone to g r a f j e s t spojny bool odpowiedz = true ; i f ( czyodwiedzony [ i ] == f a l s e ){ odpowiedz = f a l s e ; std : : cout << ( odpowiedz? TAK\n : NIE\n ) ; return 0 ; } // main 6.2 Rozwiązanie w Javie import java. u t i l. Scanner ; import java. u t i l. Vector ; import java. u t i l. ArrayDeque ; public class RKI BSF Spojnosc { public s t a t i c void main ( S t r i n g [ ] a r g s ) { // wczytujemy g r a f Scanner s = new Scanner ( System. i n ) ; int n = s. n e x t I n t ( ) ; int m =s. n e x t I n t ( ) ; Vector<Vector<I n t e g e r >> krawedzie = new Vector<Vector<I n t e g e r >>(); Vector<I n t e g e r > v = new Vector<I n t e g e r >(); krawedzie. add ( v ) ; // wczytujemy krawedzie for ( int i =0; i <m; i ++){ int a = s. n e x t I n t ( ) ; int b = s. n e x t I n t ( ) ; krawedzie. get ( a ). add ( b ) ; krawedzie. get ( b ). add ( a ) ; // ustalamy w i e r z c h o e k s t a r t o w y int startowy = 0 ; 12
13 // t a b l i c a pomocnicza i k o l e j k a boolean czyodwiedzony [ ] = new boolean [ n ] ; czyodwiedzony [ i ] = f a l s e ; ArrayDeque<I n t e g e r > k o l e j k a = new ArrayDeque<I n t e g e r >(); k o l e j k a. addlast ( startowy ) ; czyodwiedzony [ startowy ] = true ; // dopoki sa w k o l e j c e j a k i e s elementy while ( k o l e j k a. s i z e ( ) > 0){ // zdejmujemy w i e r z c h o l e k z k o l e j k i int w i e r z c h o l e k = k o l e j k a. removefirst ( ) ; // przegladamy kazdego z j e g o sasiadow for ( int i =0; i < krawedzie. get ( w i e r z c h o l e k ). s i z e ( ) ; i ++){ int s a s i a d = krawedzie. get ( w i e r z c h o l e k ). get ( i ) ; i f ( czyodwiedzony [ s a s i a d ] == f a l s e ){ czyodwiedzony [ s a s i a d ] = true ; k o l e j k a. add ( s a s i a d ) ; } // w h i l e // j e z e l i j a k i s w i e r z c h o l e k p o z o s t a l nieodwiedzony to g r a f j e s t n i e s p o j n y boolean odpowiedz = true ; i f ( czyodwiedzony [ i ] == f a l s e ){ odpowiedz = f a l s e ; System. out. format ( %s \n, odpowiedz? TAK : NIE ) ; } // main } // c l a s s 7 Spójne składowe w grafie Spójna składowa grafu jest podgrafem (intuicyjnie można myśleć o tym jak o fragmencie oryginalnego grafu) który: jest spójny, jest największy spośród podgrafów spójnych, tj. albo zawiera wszystkie wierzchołki i krawędzie oryginalnego, albo po dodaniu dodatkowego wierzchołka podgraf będzie niespójny. Jeżeli graf jest spójny, to sam jest jednocześnie swoją jedyną spójną składową. Jeżeli graf nie jest spójny, to zawiera więcej niż jedną spójną składową. Rozważmy przykład na rysunku 3. Graf ma trzy spójne składowe: 1, 2, 3, 5, 6 4, 7, 8 9 Aby je znaleźć należy skorzystać np. z przeszukiwania grafu omawianego w tej lekcji: 1. Każdemu z wierzchołków przypisujemy 1, oznacza to, że jeszcze nie był odwiedzony; gdy wierzchołek zostanie odwiedzony zostanie mu przypisany numer jego składowej. 2. Dopóki w grafie są wierzchołki bez przypisanego numeru powtarzamy: wybieramy dowolny wierzchołek, który jeszcze nie ma przypisanej składowej, przypisujemy mu kolejny, nie używany numer, startując z wybranego wierzchołka przeszukujemy graf, wszystkie odwiedzone wierzchołki dostają ten sam numer składowej, co startowy. W tym algorytmie przeszukiwanie grafu może być uruchamiane wielokrotnie, za każdym razem z innego wierzchołka. Stanowi zaledwie jedną, choć niezwykle ważną, śrubkę w większej machinie. 13
14 8 Zadanie spójne składowe Napisz program który, wczyta kolejno: n liczbę wierzchołków w grafie, n < 10000, m liczbę krawędzi w grafie m < , Rysunek 3: Graf oraz jego składowe spójne m par liczb a i b oddzielonych spacjami, które będą krawędziami w grafie. Krawędzie będą indeksowane liczbami od 0 do n 1 włącznie. Następnie program powinien wypisać wszystkie spójne składowe grafu w następującym formacie: wierzchołki należące do tej samej składowej powinny być posortowane rosnąco i zgrupowane w nawiasy kwadratowe [ ]. kolejność występowania składowych powinna być posortowana rosnąco według pierwszego elementu w danej składowej Przykładowe dane: Odpowiedź: [ ] Przykładowe dane: Odpowiedź: [ 0 2 ] [ 1 ] Wskazówki: Jedno przeszukiwanie grafu znajdzie jedną składową. Algorytm należy powtarzać startując z różnych punktów tak długo aż nie pokryje całego grafu. Ze względu na wymaganą kolejność wypisywania, jako startowy wierzchołek dobrze jest wybrać najniższy, który nie należy jeszcze do żadnej składowej. 14
15 Wykorzystaj poznane wektory do zapamiętywania wierzchołków w danej składowej. Pamiętaj, że muszą zostać posortowane przed wypisaniem. Pamiętaj, że rozmiar macierzy sąsiedztwa, która przechowuje krawędzie, rośnie kwadratowo wraz z liczbą wierzchołków. 15
RKI Zajęcia 14 Przeszukiwanie grafu w głąb
RKI Zajęcia 14 Przeszukiwanie grafu w głąb Piersa Jarosław 2010-05-09 1 Wprowadzenie Natenczas Wojski chwycił na taśmie przypięty Swój róg bawoli, długi, cętkowany, kręty Jak wąż boa, oburącz do ust go
Bardziej szczegółowoGrafem nazywamy strukturę G = (V, E): V zbiór węzłów lub wierzchołków, Grafy dzielimy na grafy skierowane i nieskierowane:
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
Bardziej szczegółowoPrzykłady grafów. Graf prosty, to graf bez pętli i bez krawędzi wielokrotnych.
Grafy Graf Graf (ang. graph) to zbiór wierzchołków (ang. vertices), które mogą być połączone krawędziami (ang. edges) w taki sposób, że każda krawędź kończy się i zaczyna w którymś z wierzchołków. Graf
Bardziej szczegółowoa) 7 b) 19 c) 21 d) 34
Zadanie 1. Pytania testowe dotyczące podstawowych własności grafów. Zadanie 2. Przy każdym z zadań może się pojawić polecenie krótkiej charakterystyki algorytmu. Zadanie 3. W zadanym grafie sprawdzenie
Bardziej szczegółowoOgólne wiadomości o grafach
Ogólne wiadomości o grafach Algorytmy i struktury danych Wykład 5. Rok akademicki: / Pojęcie grafu Graf zbiór wierzchołków połączonych za pomocą krawędzi. Podstawowe rodzaje grafów: grafy nieskierowane,
Bardziej szczegółowoStruktury danych i złożoność obliczeniowa Wykład 5. Prof. dr hab. inż. Jan Magott
Struktury danych i złożoność obliczeniowa Wykład. Prof. dr hab. inż. Jan Magott Algorytmy grafowe: podstawowe pojęcia, reprezentacja grafów, metody przeszukiwania, minimalne drzewa rozpinające, problemy
Bardziej szczegółowoAlgorytmiczna teoria grafów
Przedmiot fakultatywny 20h wykładu + 20h ćwiczeń 21 lutego 2014 Zasady zaliczenia 1 ćwiczenia (ocena): kolokwium, zadania programistyczne (implementacje algorytmów), praca na ćwiczeniach. 2 Wykład (egzamin)
Bardziej szczegółowo1. Algorytmy przeszukiwania. Przeszukiwanie wszerz i w głąb.
1. Algorytmy przeszukiwania. Przeszukiwanie wszerz i w głąb. Algorytmy przeszukiwania w głąb i wszerz są najczęściej stosowanymi algorytmami przeszukiwania. Wykorzystuje się je do zbadania istnienia połączenie
Bardziej szczegółowoAlgorytmy grafowe. Wykład 2 Przeszukiwanie grafów. Tomasz Tyksiński CDV
Algorytmy grafowe Wykład 2 Przeszukiwanie grafów Tomasz Tyksiński CDV Rozkład materiału 1. Podstawowe pojęcia teorii grafów, reprezentacje komputerowe grafów 2. Przeszukiwanie grafów 3. Spójność grafu,
Bardziej szczegółowo8. Wektory. Przykłady Napisz program, który pobierze od użytkownika 10 liczb, a następnie wypisze je w kolejności odwrotnej niż podana.
8. Wektory Przykłady 8.1. Napisz program, który pobierze od użytkownika 10 liczb, a następnie wypisze je w kolejności odwrotnej niż podana. Uwaga! Kod poniżej. To zadanie można rozwiązać przy użyciu wiedzy
Bardziej szczegółowoReprezentacje grafów nieskierowanych Reprezentacje grafów skierowanych. Wykład 2. Reprezentacja komputerowa grafów
Wykład 2. Reprezentacja komputerowa grafów 1 / 69 Macierz incydencji Niech graf G będzie grafem nieskierowanym bez pętli o n wierzchołkach (x 1, x 2,..., x n) i m krawędziach (e 1, e 2,..., e m). 2 / 69
Bardziej szczegółowoWstęp do programowania
wykład 6 Agata Półrola Wydział Matematyki i Informatyki UŁ sem. zimowy 2017/2018 Losowanie liczb całkowitych Dostępne biblioteki Najprostsze losowanie liczb całkowitych można wykonać za pomocą funkcji
Bardziej szczegółowoZofia Kruczkiewicz, Algorytmu i struktury danych, Wykład 14, 1
Wykład Algorytmy grafowe metoda zachłanna. Właściwości algorytmu zachłannego:. W przeciwieństwie do metody programowania dynamicznego nie występuje etap dzielenia na mniejsze realizacje z wykorzystaniem
Bardziej szczegółowoKurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016
Wykład 9 28 kwiecień 2016 Java Collections Framework (w C++ Standard Template Library) Kolekcja (kontener) Obiekt grupujacy/przechowuj acy jakieś elementy (obiekty lub wartości). Przykładami kolekcji sa
Bardziej szczegółowoProgramowanie - wykład 4
Programowanie - wykład 4 Filip Sośnicki Wydział Fizyki Uniwersytet Warszawski 20.03.2019 Przypomnienie Prosty program liczący i wyświeltający wartość silni dla wprowadzonej z klawiatury liczby: 1 # include
Bardziej szczegółowoDynamiczny przydział pamięci w języku C. Dynamiczne struktury danych. dr inż. Jarosław Forenc. Metoda 1 (wektor N M-elementowy)
Rok akademicki 2012/2013, Wykład nr 2 2/25 Plan wykładu nr 2 Informatyka 2 Politechnika Białostocka - Wydział Elektryczny Elektrotechnika, semestr III, studia niestacjonarne I stopnia Rok akademicki 2012/2013
Bardziej szczegółowoTablice mgr Tomasz Xięski, Instytut Informatyki, Uniwersytet Śląski Katowice, 2011
Tablice mgr Tomasz Xięski, Instytut Informatyki, Uniwersytet Śląski Katowice, 2011 Załóżmy, że uprawiamy jogging i chcemy monitorować swoje postępy. W tym celu napiszemy program, który zlicza, ile czasu
Bardziej szczegółowoPodstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.
M. Trzebiński C++ 1/14 Podstawy języka C++ Maciej Trzebiński Instytut Fizyki Jądrowej Polskiej Akademii Nauk Praktyki studenckie na LHC IVedycja,2016r. IFJ PAN Przygotowanie środowiska pracy Niniejsza
Bardziej szczegółowoAlgorytmy i Struktury Danych.
Algorytmy i Struktury Danych. Grafy dr hab. Bożena Woźna-Szcześniak bwozna@gmail.com Jan Długosz University, Poland Wykład 9 Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 9 1 / 20
Bardziej szczegółowoPorównanie algorytmów wyszukiwania najkrótszych ścieżek międz. grafu. Daniel Golubiewski. 22 listopada Instytut Informatyki
Porównanie algorytmów wyszukiwania najkrótszych ścieżek między wierzchołkami grafu. Instytut Informatyki 22 listopada 2015 Algorytm DFS w głąb Algorytm przejścia/przeszukiwania w głąb (ang. Depth First
Bardziej szczegółowoAlgorytmy równoległe. Rafał Walkowiak Politechnika Poznańska Studia inżynierskie Informatyka 2010
Algorytmy równoległe Rafał Walkowiak Politechnika Poznańska Studia inżynierskie Informatyka Znajdowanie maksimum w zbiorze n liczb węzły - maksimum liczb głębokość = 3 praca = 4++ = 7 (operacji) n - liczność
Bardziej szczegółowoInformacje wstępne #include <nazwa> - derektywa procesora umożliwiająca włączenie do programu pliku o podanej nazwie. Typy danych: char, signed char
Programowanie C++ Informacje wstępne #include - derektywa procesora umożliwiająca włączenie do programu pliku o podanej nazwie. Typy danych: char, signed char = -128 do 127, unsigned char = od
Bardziej szczegółowoWstęp do Programowania potok funkcyjny
Wstęp do Programowania potok funkcyjny Marcin Kubica 2010/2011 Outline 1 Podstawowe pojęcia Definition Graf = wierzchołki + krawędzie. Krawędzie muszą mieć różne końce. Między dwoma wierzchołkami może
Bardziej szczegółowoZasady programowania Dokumentacja
Marcin Kędzierski gr. 14 Zasady programowania Dokumentacja Wstęp 1) Temat: Przeszukiwanie pliku za pomocą drzewa. 2) Założenia projektu: a) Program ma pobierać dane z pliku wskazanego przez użytkownika
Bardziej szczegółowo1 Podstawy c++ w pigułce.
1 Podstawy c++ w pigułce. 1.1 Struktura dokumentu. Kod programu c++ jest zwykłym tekstem napisanym w dowolnym edytorze. Plikowi takiemu nadaje się zwykle rozszerzenie.cpp i kompiluje za pomocą kompilatora,
Bardziej szczegółowoWykład 10 Grafy, algorytmy grafowe
. Typy złożoności obliczeniowej Wykład Grafy, algorytmy grafowe Typ złożoności oznaczenie n Jedna operacja trwa µs 5 logarytmiczna lgn. s. s.7 s liniowa n. s.5 s. s Logarytmicznoliniowa nlgn. s.8 s.4 s
Bardziej szczegółowoMatematyczne Podstawy Informatyki
Matematyczne Podstawy Informatyki dr inż. Andrzej Grosser Instytut Informatyki Teoretycznej i Stosowanej Politechnika Częstochowska Rok akademicki 03/0 Przeszukiwanie w głąb i wszerz I Przeszukiwanie metodą
Bardziej szczegółowoRozwiązanie. #include <cstdlib> #include <iostream> using namespace std;
Programowanie C++ Zadanie 1 Napisz program do obliczenia sumy i iloczynu ciągu liczb zakooczonego liczbą zero. Zakładamy, że ciąg zawiera co najmniej jedną liczbę (założenie to jest konieczne przy obliczeniu
Bardziej szczegółowoWstęp do programowania
wykład 5 Agata Półrola Wydział Matematyki i Informatyki UŁ sem. zimowy 2016/2017 Zadanie o kotach z poprzedniego wykładu # include < iostream > using namespace std ; int main (){ int rozmiar_ rodzinki,
Bardziej szczegółowoMatematyka dyskretna
Matematyka dyskretna Wykład 13: Teoria Grafów Gniewomir Sarbicki Literatura R.J. Wilson Wprowadzenie do teorii grafów Definicja: Grafem (skończonym, nieskierowanym) G nazywamy parę zbiorów (V (G), E(G)),
Bardziej szczegółowoSortowanie topologiczne skierowanych grafów acyklicznych
Sortowanie topologiczne skierowanych grafów acyklicznych Metody boolowskie w informatyce Robert Sulkowski http://robert.brainusers.net 23 stycznia 2010 1 Definicja 1 (Cykl skierowany). Niech C = (V, A)
Bardziej szczegółowoWstęp do programowania
wykład 7 Agata Półrola Wydział Matematyki i Informatyki UŁ sem. zimowy 2016/2017 Losowanie liczb całkowitych Dostępne biblioteki Najprostsze losowanie liczb całkowitych można wykonać za pomocą funkcji
Bardziej szczegółowoPodstawy Programowania C++
Wykład 3 - podstawowe konstrukcje Instytut Automatyki i Robotyki Warszawa, 2014 Wstęp Plan wykładu Struktura programu, instrukcja przypisania, podstawowe typy danych, zapis i odczyt danych, wyrażenia:
Bardziej szczegółowoWstęp do programowania
wykład 4 Agata Półrola Wydział Matematyki i Informatyki UŁ sem. zimowy 2017/2018 Pętle wykonujące się podaną liczbę razy Jeśli chcemy wykonać pewien fragment programu określoną liczbę razy, możemy użyć
Bardziej szczegółowoPodstawy programowania skrót z wykładów:
Podstawy programowania skrót z wykładów: // komentarz jednowierszowy. /* */ komentarz wielowierszowy. # include dyrektywa preprocesora, załączająca biblioteki (pliki nagłówkowe). using namespace
Bardziej szczegółowoKurs programowania. Wykład 9. Wojciech Macyna
Wykład 9 Java Collections Framework (w C++ Standard Template Library) Kolekcja (kontener) Obiekt grupujacy/przechowuj acy jakieś elementy (obiekty lub wartości). Przykładami kolekcji sa zbiór, lista czy
Bardziej szczegółowoProgramowanie Obiektowo Zorientowane w języku c++ Przestrzenie nazw
Programowanie Obiektowo Zorientowane w języku c++ Przestrzenie nazw Mirosław Głowacki 1 1 Akademia Górniczo-Hutnicza im. Stanisława Staszica w Ktrakowie Wydział Inżynierii Metali i Informatyki Stosowanej
Bardziej szczegółowoznajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.
Część XVI C++ Funkcje Jeśli nasz program rozrósł się już do kilkudziesięciu linijek, warto pomyśleć o jego podziale na mniejsze części. Poznajmy więc funkcje. Szybko się przekonamy, że funkcja to bardzo
Bardziej szczegółowoPytania sprawdzające wiedzę z programowania C++
Pytania sprawdzające wiedzę z programowania C++ Wstęp 1. Zaprezentuj mechanikę tworzenia programu napisanego w języku C++. 2. Co to jest kompilacja? 3. Co to jest konsolidacja? 4. Co to jest kod wykonywalny?
Bardziej szczegółowo. Podstawy Programowania 2. Grafy i ich reprezentacje. Arkadiusz Chrobot. 9 czerwca 2016
Podstawy Programowania 2 Grafy i ich reprezentacje Arkadiusz Chrobot Zakład Informatyki 9 czerwca 2016 1 42 Plan 1 Wstęp 2 Teoria grafów 3 Grafy jako struktury danych 4 Zastosowania grafów 2 42 Wstęp Wstęp
Bardziej szczegółowoZajęcia nr 5 Algorytmy i wskaźniki. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej
Zajęcia nr 5 Algorytmy i wskaźniki dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej Plan Zapis i odczyt z plików tekstowych O tablicach ciąg dalszy Referencje
Bardziej szczegółowoWstęp do Informatyki zadania ze złożoności obliczeniowej z rozwiązaniami
Wstęp do Informatyki zadania ze złożoności obliczeniowej z rozwiązaniami Przykład 1. Napisz program, który dla podanej liczby n wypisze jej rozkład na czynniki pierwsze. Oblicz asymptotyczną złożoność
Bardziej szczegółowoMatematyczne Podstawy Informatyki
Matematyczne Podstawy Informatyki dr inż. Andrzej Grosser Instytut Informatyki Teoretycznej i Stosowanej Politechnika Częstochowska Rok akademicki 2013/2014 Informacje podstawowe 1. Konsultacje: pokój
Bardziej szczegółowoPętle i tablice. Spotkanie 3. Pętle: for, while, do while. Tablice. Przykłady
Pętle i tablice. Spotkanie 3 Dr inż. Dariusz JĘDRZEJCZYK Pętle: for, while, do while Tablice Przykłady 11/26/2016 AGH, Katedra Informatyki Stosowanej i Modelowania 2 Pętla w największym uproszczeniu służy
Bardziej szczegółowoWstęp do informatyki- wykład 7
1 Wstęp do informatyki- wykład 7 Operatory przypisania, złożone operatory przypisania, Pętla while i do..while Treści prezentowane w wykładzie zostały oparte o: S. Prata, Język C++. Szkoła programowania.
Bardziej szczegółowoPodstawy Programowania 2 Grafy i ich reprezentacje. Plan. Wstęp. Teoria grafów Graf skierowany. Notatki. Notatki. Notatki. Notatki.
Podstawy Programowania Grafy i ich reprezentacje Arkadiusz Chrobot Zakład Informatyki 7 maja 09 / 4 Plan Wstęp Zastosowania grafów / 4 Wstęp Grafy są w informatyce strukturami danych stosowanymi w wielu
Bardziej szczegółowoPodstawowe własności grafów. Wykład 3. Własności grafów
Wykład 3. Własności grafów 1 / 87 Suma grafów Niech będą dane grafy proste G 1 = (V 1, E 1) oraz G 2 = (V 2, E 2). 2 / 87 Suma grafów Niech będą dane grafy proste G 1 = (V 1, E 1) oraz G 2 = (V 2, E 2).
Bardziej szczegółowoProgramowanie i struktury danych
Programowanie i struktury danych 1 / 30 STL Standard Template Library, STL (ang. = Standardowa Biblioteka Wzorców) biblioteka C++ zawierająca szablony (wzorce), które umożliwiają wielokrotne użycie. Główne
Bardziej szczegółowoPole wielokąta. Wejście. Wyjście. Przykład
Pole wielokąta Liczba punktów: 60 Limit czasu: 1-3s Limit pamięci: 26MB Oblicz pole wielokąta wypukłego. Wielokąt wypukły jest to wielokąt, który dla dowolnych jego dwóch punktów zawiera również odcinek
Bardziej szczegółowo4. Funkcje. Przykłady
4. Funkcje Przykłady 4.1. Napisz funkcję kwadrat, która przyjmuje jeden argument: długość boku kwadratu i zwraca pole jego powierzchni. Używając tej funkcji napisz program, który obliczy pole powierzchni
Bardziej szczegółowoAiSD zadanie trzecie
AiSD zadanie trzecie Gliwiński Jarosław Marek Kruczyński Konrad Marek Grupa dziekańska I5 5 czerwca 2008 1 Wstęp Celem postawionym przez zadanie trzecie było tzw. sortowanie topologiczne. Jest to typ sortowania
Bardziej szczegółowoStruktury Struktura polami struct struct struct struct
Struktury Struktura jest zbiorem zmiennych występujących pod wspólna nazwą. Zmienne wchodzące w skład struktury nazywane są polami lub elementami, a czasem członkami struktury. Struktury używamy, jeśli
Bardziej szczegółowoPodstawy programowania. Wykład: 9. Łańcuchy znaków. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD
Podstawy programowania Wykład: 9 Łańcuchy znaków 1 dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD Tablica znaków w językach C i C++ (oraz pochodnych) łańcuch znaków przechowywany jest jako
Bardziej szczegółowoPodstawy programowania, Poniedziałek , 8-10 Projekt, część 1
Podstawy programowania, Poniedziałek 30.05.2016, 8-10 Projekt, część 1 1. Zadanie Projekt polega na stworzeniu logicznej gry komputerowej działającej w trybie tekstowym o nazwie Minefield. 2. Cele Celem
Bardziej szczegółowo2. Tablice. Tablice jednowymiarowe - wektory. Algorytmy i Struktury Danych
2. Tablice Tablica to struktura danych przechowująca elementy jednego typu (jednorodna). Dostęp do poszczególnych elementów składowych jest możliwy za pomocą indeksów. Rozróżniamy następujące typy tablic:
Bardziej szczegółowoZadania do wykonania. Rozwiązując poniższe zadania użyj pętlę for.
Zadania do wykonania Rozwiązując poniższe zadania użyj pętlę for. 1. apisz program, który przesuwa w prawo o dwie pozycje zawartość tablicy 10-cio elementowej liczb całkowitych tzn. element t[i] dla i=2,..,9
Bardziej szczegółowoZajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej
Zajęcia nr 2 Programowanie strukturalne dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej Pętla while #include using namespace std; int main ()
Bardziej szczegółowoMatematyka dyskretna - 7.Drzewa
Matematyka dyskretna - 7.Drzewa W tym rozdziale zajmiemy się drzewami: specjalnym przypadkiem grafów. Są one szczególnie przydatne do przechowywania informacji, umożliwiającego szybki dostęp do nich. Definicja
Bardziej szczegółowo. Podstawy Programowania 2. Algorytmy dfs i bfs. Arkadiusz Chrobot. 2 czerwca 2019
Podstawy Programowania Algorytmy dfs i bfs Arkadiusz Chrobot Zakład Informatyki czerwca 09 / 70 Plan Wstęp Algorytm BFS Podsumowanie / 70 Wstęp Wstęp Istnieje wiele algorytmów związanych z grafami, które
Bardziej szczegółowoInstrukcje dla zawodników
Instrukcje dla zawodników Nie otwieraj arkusza z zadaniami dopóki nie zostaniesz o to poproszony. Instrukcje poniżej zostaną ci odczytane i wyjaśnione. 1. Arkusz składa się z 3 zadań. 2. Każde zadanie
Bardziej szczegółowoDigraf o V wierzchołkach posiada V 2 krawędzi, zatem liczba różnych digrafów o V wierzchołkach wynosi 2 VxV
Graf skierowany (digraf) zbiór wierzchołków i zbiór krawędzi skierowanych łączących (co najwyżej jeden raz) uporządkowane pary wierzchołków. Mówimy wtedy, że krawędź łączy pierwszy wierzchołek z drugim
Bardziej szczegółowoWykład 7. Algorytmy grafowe
Wykład Algorytmy grafowe Algorytmy grafowe i podstawowe algorytmy przeszukiwania Problem Definicje i własności Reprezentacja Przeszukiwanie wszerz (Breadthirst Search) Przeszukiwanie w głąb (Depthirst
Bardziej szczegółowoAlgorytm DFS Wprowadzenie teoretyczne. Algorytm DFS Wprowadzenie teoretyczne. Algorytm DFS Animacja. Algorytm DFS Animacja. Notatki. Notatki.
Podstawy Programowania Algorytmy dfs i bfs Arkadiusz Chrobot Zakład Informatyki czerwca 09 / 70 Plan Wstęp Podsumowanie / 70 Wstęp Istnieje wiele algorytmów związanych z grafami, które w skrócie nazywane
Bardziej szczegółowoPodstawy algorytmiki i programowania - wykład 4 C-struktury
1 Podstawy algorytmiki i programowania - wykład 4 C-struktury Treści prezentowane w wykładzie zostały oparte o: S. Prata, Język C++. Szkoła programowania. Wydanie VI, Helion, 2012 www.cplusplus.com Jerzy
Bardziej szczegółowoZnajdowanie wyjścia z labiryntu
Znajdowanie wyjścia z labiryntu Zadanie to wraz z problemem pakowania najcenniejszego plecaka należy do problemów optymalizacji, które dotyczą znajdowania najlepszego rozwiązania wśród wielu możliwych
Bardziej szczegółowoWydział Matematyki I Informatyki ul. Słoneczna Olsztyn
Klucz Napisać program sprawdzający czy dany klucz pasuje do danego zamka. Dziurka w zamku reprezentowana jest w postaci tablicy zero-jedynkowej i jest spójna. Klucz zakodowany jest jako ciąg par liczb
Bardziej szczegółowoPodstawy Programowania
Podstawy Programowania Monika Wrzosek Instytut Matematyki Uniwersytet Gdański Matematyka 2017/18 Monika Wrzosek (IM UG) Podstawy Programowania 1 / 119 Sprawy organizacyjne E-mail: mwrzosek@mat.ug.edu.pl
Bardziej szczegółowoAlgorytm Dijkstry znajdowania najkrótszej ścieżki w grafie
Algorytm Dijkstry znajdowania najkrótszej ścieżki w grafie Używane struktury danych: V - zbiór wierzchołków grafu, V = {1,2,3...,n} E - zbiór krawędzi grafu, E = {(i,j),...}, gdzie i, j Î V i istnieje
Bardziej szczegółowoKurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016
Wykład 1 3 marca 2016 Słowa kluczowe języka Java abstract, break, case, catch, class, const, continue, default, do, else, enum, extends, final, finally, for, goto, if, implements, import, instanceof, interface,
Bardziej szczegółowoAlgorytmy Równoległe i Rozproszone Część V - Model PRAM II
Algorytmy Równoległe i Rozproszone Część V - Model PRAM II Łukasz Kuszner pokój 209, WETI http://www.sphere.pl/ kuszner/ kuszner@sphere.pl Oficjalna strona wykładu http://www.sphere.pl/ kuszner/arir/ 2005/06
Bardziej szczegółowoProf. Danuta Makowiec Instytut Fizyki Teoretycznej i Astrofizyki pok. 353, tel danuta.makowiec at gmail.com
Programowanie wykład dla I roku bioinformatyki semestr letni 2013 Prof. Danuta Makowiec Instytut Fizyki Teoretycznej i Astrofizyki pok. 353, tel. 58 523 2466 e-mail: danuta.makowiec at gmail.com Cel bloku
Bardziej szczegółowoAlgorytmy i złożoności. Wykład 3. Listy jednokierunkowe
Algorytmy i złożoności Wykład 3. Listy jednokierunkowe Wstęp. Lista jednokierunkowa jest strukturą pozwalającą na pamiętanie danych w postaci uporzadkowanej, a także na bardzo szybkie wstawianie i usuwanie
Bardziej szczegółowo1 Pierwsze kroki w C++ cz.3 2 Obsługa plików
1 Pierwsze kroki w C++ cz.3 2 Obsługa plików Do pracy z plikami zewnętrznymi niezbędna będzie biblioteka fstream. Udostępnia ona programiście narzędzia do zapisu i odczytu plików. 2.1 Typ zmiennej fstream.
Bardziej szczegółowoPodstawy programowania 2. Temat: Drzewa binarne. Przygotował: mgr inż. Tomasz Michno
Instrukcja laboratoryjna 5 Podstawy programowania 2 Temat: Drzewa binarne Przygotował: mgr inż. Tomasz Michno 1 Wstęp teoretyczny Drzewa są jedną z częściej wykorzystywanych struktur danych. Reprezentują
Bardziej szczegółowoC-struktury wykład. Dorota Pylak
C-struktury wykład Dorota Pylak C-struktury W języku C++, jak w każdym języku obiektowym, mamy możliwość definiowania własnych typów danych, wraz z określeniem operacji, jakie na tych danych można wykonywać.
Bardziej szczegółowodo instrukcja while (wyrażenie);
Instrukcje pętli -ćwiczenia Instrukcja while Pętla while (póki) powoduje powtarzanie zawartej w niej sekwencji instrukcji tak długo, jak długo zaczynające pętlę wyrażenie pozostaje prawdziwe. while ( wyrażenie
Bardziej szczegółowoProgramowanie obiektowe
Programowanie obiektowe Sieci powiązań Paweł Daniluk Wydział Fizyki Jesień 2014 P. Daniluk (Wydział Fizyki) PO w. IX Jesień 2014 1 / 24 Sieci powiązań Można (bardzo zgrubnie) wyróżnić dwa rodzaje powiązań
Bardziej szczegółowoutworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy,
Lista 3 Zestaw I Zadanie 1. Zaprojektować i zaimplementować funkcje: utworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy, zapisz
Bardziej szczegółowoKontrola przebiegu programu
Kontrola przebiegu programu Wykład 9 Instrukcje sterujące: pętle rozgałęzienia skoki PRZYPOMINAJKA Zadanie : Zaprojektuj rekurencyjny przepis na wyznaczenie największej takiej liczby m, że 2 m jest podzielnikiem
Bardziej szczegółowoWstęp do programowania. Zastosowania stosów i kolejek. Piotr Chrząstowski-Wachtel
Wstęp do programowania Zastosowania stosów i kolejek Piotr Chrząstowski-Wachtel FIFO - LIFO Kolejki i stosy służą do przechowywania wartości zbiorów dynamicznych, czyli takich, które powstają przez dodawanie
Bardziej szczegółowoOpis zagadnieo 1-3. Iteracja, rekurencja i ich realizacja
Opis zagadnieo 1-3 Iteracja, rekurencja i ich realizacja Iteracja Iteracja to czynnośd powtarzania (najczęściej wielokrotnego) tej samej instrukcji (albo wielu instrukcji) w pętli. Mianem iteracji określa
Bardziej szczegółowoPodstawy języka C++ Maciej Trzebiński. Praktyki studenckie na LHC IFJ PAN. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. M. Trzebiński C++ 1/16
M. Trzebiński C++ 1/16 Podstawy języka C++ Maciej Trzebiński Instytut Fizyki Jądrowej Polskiej Akademii Nauk Praktyki studenckie na LHC IFJ PAN 6lipca2015 Uruchomienie maszyny w CC1 M. Trzebiński C++ 2/16
Bardziej szczegółowotablica: dane_liczbowe
TABLICE W JĘZYKU C/C++ tablica: dane_liczbowe float dane_liczbowe[5]; dane_liczbowe[0]=12.5; dane_liczbowe[1]=-0.2; dane_liczbowe[2]= 8.0;... 12.5-0.2 8.0...... 0 1 2 3 4 indeksy/numery elementów Tablica
Bardziej szczegółowoKonstrukcje warunkowe Pętle
* Konstrukcje warunkowe Pętle *Instrukcja if sposób na sprawdzanie warunków *Konstrukcja: if(warunek) else { instrukcje gdy warunek spełniony} {instrukcje gdy warunek NIE spełniony} * 1. Wylicz całkowity
Bardziej szczegółowoKurs programowania. Wykład 3. Wojciech Macyna. 22 marca 2019
Wykład 3 22 marca 2019 Klasy wewnętrzne Klasa wewnętrzna class A {... class B {... }... } Klasa B jest klasa wewnętrzna w klasie A. Klasa A jest klasa otaczajac a klasy B. Klasy wewnętrzne Właściwości
Bardziej szczegółowoWstęp do Programowania potok funkcyjny
Wstęp do Programowania potok funkcyjny Marcin Kubica 2010/2011 Outline 1 BFS DFS Algorytm Dijkstry Algorytm Floyda-Warshalla Podstawowe pojęcia Definition Graf = wierzchołki + krawędzie. Krawędzie muszą
Bardziej szczegółowoMatematyka dyskretna. Andrzej Łachwa, UJ, /14
Matematyka dyskretna Andrzej Łachwa, UJ, 2016 andrzej.lachwa@uj.edu.pl 13/14 Grafy podstawowe definicje Graf to para G=(V, E), gdzie V to niepusty i skończony zbiór, którego elementy nazywamy wierzchołkami
Bardziej szczegółowoWstęp do sieci neuronowych, wykład 11 Łańcuchy Markova
Wstęp do sieci neuronowych, wykład 11 Łańcuchy Markova M. Czoków, J. Piersa 2010-12-21 1 Definicja Własności Losowanie z rozkładu dyskretnego 2 3 Łańcuch Markova Definicja Własności Losowanie z rozkładu
Bardziej szczegółowodr inż. Paweł Myszkowski Wykład nr 11 ( )
dr inż. Paweł Myszkowski Politechnika Białostocka Wydział Elektryczny Elektronika i Telekomunikacja, semestr II, studia stacjonarne I stopnia Rok akademicki 2015/2016 Wykład nr 11 (11.05.2016) Plan prezentacji:
Bardziej szczegółowododatkowe operacje dla kopca binarnego: typu min oraz typu max:
ASD - ćwiczenia IX Kopce binarne własność porządku kopca gdzie dla każdej trójki wierzchołków kopca (X, Y, Z) porządek etykiet elem jest następujący X.elem Y.elem oraz Z.elem Y.elem w przypadku kopca typu
Bardziej szczegółowoTeoria grafów dla małolatów. Andrzej Przemysław Urbański Instytut Informatyki Politechnika Poznańska
Teoria grafów dla małolatów Andrzej Przemysław Urbański Instytut Informatyki Politechnika Poznańska Wstęp Matematyka to wiele różnych dyscyplin Bowiem świat jest bardzo skomplikowany wymaga rozważenia
Bardziej szczegółowoPodstawy i języki programowania
Podstawy i języki programowania Laboratorium 2 - wprowadzenie do zmiennych mgr inż. Krzysztof Szwarc krzysztof@szwarc.net.pl Sosnowiec, 23 października 2017 1 / 26 mgr inż. Krzysztof Szwarc Podstawy i
Bardziej szczegółowoCzęść 4 życie programu
1. Struktura programu c++ Ogólna struktura programu w C++ składa się z kilku części: część 1 część 2 część 3 część 4 #include int main(int argc, char *argv[]) /* instrukcje funkcji main */ Część
Bardziej szczegółowoProgramowanie obiektowe
Programowanie obiektowe Sieci powiązań Paweł Daniluk Wydział Fizyki Jesień 2015 P. Daniluk (Wydział Fizyki) PO w. IX Jesień 2015 1 / 21 Sieci powiązań Można (bardzo zgrubnie) wyróżnić dwa rodzaje powiązań
Bardziej szczegółowoDariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki
Dariusz Brzeziński Politechnika Poznańska, Instytut Informatyki int getmax (int a, int b) { return (a > b? a : b); float getmax (float a, float b) { return (a > b? a : b); long getmax (long a, long b)
Bardziej szczegółowoZadanie 1 Przygotuj algorytm programu - sortowanie przez wstawianie.
Sortowanie Dane wejściowe: ciąg n-liczb (kluczy) (a 1, a 2, a 3,..., a n 1, a n ) Dane wyjściowe: permutacja ciągu wejściowego (a 1, a 2, a 3,..., a n 1, a n) taka, że a 1 a 2 a 3... a n 1 a n. Będziemy
Bardziej szczegółowoDla każdej operacji łącznie tworzenia danych i zapisu ich do pliku przeprowadzić pomiar czasu wykonania polecenia. Wyniki przedstawić w tabelce.
Przygotować program tworzący tablicę dwuwymiarową zawierającą zestawy 10 2, 10 4, 10 6 liczb losowych zmiennoprzecinkowych. Korzystając z funkcji bibliotecznych uporządkować zawartość każdego (a) wiersza
Bardziej szczegółowoUniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Ćwiczenie 3 stos Laboratorium Metod i Języków Programowania
Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych Ćwiczenie 3 stos Laboratorium Metod i Języków Programowania Celem ćwiczenia jest zapoznanie studentów z najprostszą dynamiczną strukturą
Bardziej szczegółowoInformatyka II. Laboratorium.
Informatyka II. Laboratorium. Ćwiczenie 13. Reprezentacja grafów w Java. Wyszukiwanie najkrótszej ścieżki w grafie. I. Wstęp. Grafy [1] są podstawową strukturą danych dla wielu algorytmów stosowanych w
Bardziej szczegółowo