Fastbar
Powrót do strony głównej
Trzymaj pliki na gmclan.org!
Game Maker w pytaniach i odpowiedziach!
Polska dokumentacja
Tabela wyników ligi 24
Pobierz GM
Kategorie bazy artykułów
Artykuły -> Kąciki programowania -> Algorytmy i struktury danych
Treść artykułu
Wprowadzenie do teorii grafów - cz. 2
autor: Platyna (24.05.09)
Wstęp do teorii grafów - cz. 2

Sposoby reprezentacji grafów
     Człowiekowi najłatwiej wyobrazić sobie graf jako rysunek na którym punktami oznaczamy wierzchołki, a odcinkami (lub strzałkami) krawędzie grafu. W przypadku komputera jest trochę trudniej. Nie zrozumie, jeśli mu pokażemy nasze bazgroły. ;) W tej części artykułu omówione zostaną dwa najczęściej spotykane sposoby reprezentacji grafów w programowaniu. Przedstawione zostaną ich wady, zalety, możliwości jakie nam dają a także różne sposoby implementacji.
     UWAGA W zrozumieniu poniższych treści przydatne może okazać się zaznajomienie z podstawowymi strukturami danych (listy, kolejki, stosy itp.).
Miłej lektury :)

Macierz sąsiedztwa
     Jest to chyba najbardziej intuicyjny sposób przetrzymywania grafu. Polega on na utworzeniu macierzy o liczbie kolumn i wierszy równej liczbie wierzchołków grafu. Macierz jest czymś w rodzaju prostokątnej tabeli danych o określonej liczbie wierszy i kolumn. W komórce na pozycji (i,j) (gdzie i to numer wiersza, a j numer kolumny) będziemy przechowywali wartość 1 jeżeli istnieje krawędź prowadząca od wierzchołka i do wierzchołka j lub wartość 0 jeżeli taka krawędź nie istnieje. W przypadku grafów ważonych z krawędziami o określonych wagach zamiast 1 będziemy przechowywali wagę krawędzi. Myślę, że najlepiej będzie jeśli pokażę jakiś przykład. Rysunek 2 przedstawia spójny graf skierowany oraz odpowiadającą mu macierz sąsiedztwa.

     Może teraz coś o wadach i zaletach takiej reprezentacji grafów. Największą wadą takiego rozwiązania jest jego złożoność pamięciowa. Gdy byśmy chcieli w taki sposób przechowywać graf o bardzo dużej ilości wierzchołków, np. 100.000 musieli byśmy utworzyć macierz posiadającą 10.000.000.000 komórek, a tego nie wytrzymał by żaden komputer. No, a jakie korzyści nam daje macierz sąsiedztwa? Przede wszystkim możemy w prosty sposób, w czasie stałym sprawdzić czy dane dwa wierzchołki są połączone krawędzią. W tym celu wystarczy sprawdzić zawartość jednej komórki macierzy. W równie prosty sposób możemy usunąć lub dodać nową krawędź do grafu zmieniając w tym celu jedną wartość. Niestety gorzej ma się sprawa z wyszukaniem wszystkich sąsiadów danego wierzchołka. Aby odnaleźć wszystkie wierzchołki połączone z wierzchołkiem i musimy przeszukać cały wiersz i macierzy w poszukiwaniu jedynek.
     Taka reprezentacja grafu ma jeszcze jedną wadę. Rozważmy sytuację w której od pewnego wierzchołka i do wierzchołka j prowadzi więcej niż jedna krawędź. W takim wypadku w odpowiedniej komórce zamiast wartości 1 mogli byśmy przechowywać liczbę krawędzi łączących wierzchołki i i j. Gorzej sytuacja się ma jeśli wszystkim takim krawędziom przypisane są różne wagi. Na szczęście z takimi grafami nie mamy często do czynienia.

Implementacja
     Tutaj nie ma specjalnie o czym opowiadać. Znam tylko jeden sposób implementacji macierzy sąsiedztwa i jest on bardzo prosty. Polega na utworzeniu dwuwymiarowej tablicy o obu wymiarach równych liczbie wierzchołków. Tablica ta będzie odpowiadała naszej macierzy.

Listy sąsiedztwa
     Drugą często spotykaną reprezentacją grafu są tzw. listy sąsiedztwa. Polega ona na tym, że dla każdego wierzchołka tworzymy listę jego sąsiadów (czyli wierzchołków połączonych z nim pojedynczą krawędzią). Zwykle złożoność pamięciowa takiego rozwiązania jest znacznie lepsza niż w przypadku macierzy. Dla każdego wierzchołka tworzymy tyle zmiennych ile ma on sąsiadów, a więc tyle ile istnieje krawędzi odchodzących od niego. Tak więc całkowita złożoność pamięciowa tej reprezentacji jest proporcjonalna do liczby krawędzi grafu. No, ale niestety zdarzają się przypadki w których rozwiązanie to będzie równie pamięciożerne co macierz sąsiedztwa . Rozważmy taką reprezentację dla grafu pełnego skierowanego. Będzie miał on (n*(n-1)) krawędzi, a więc będzie wymagał od nas utworzenia właśnie tylu zmiennych. Na szczęście w praktyce rzadko mamy do czynienia z takimi grafami. Rysunek 3 przestawia przykładowy niespójny graf oraz odpowiadające mu listy sąsiedztwa.

     A na co nam pozwala takie rozwiązanie? Przede wszystkim możemy w prosty sposób uzyskać informacje o wszystkich sąsiadach danego wierzchołka. Jest to bardzo użyteczne przy implementowaniu wielu algorytmów grafowych. Przy odpowiedniej implementacji również dodanie krawędzi jest niezwykle proste, gdyż sprowadza się jedynie do dodania nowego wierzchołka do odpowiedniej listy. Niestety coś za coś. Gorzej sprawa się ma jeśli chcemy sprawdzić czy istnieje krawędź prowadząca od wierzchołka i do j. W tym celu musimy przeszukać całą listę sąsiadów wierzchołka i by sprawdzić czy występuje na niej wierzchołek j. Podobnie wygląda usuwanie krawędzi. Należy odnaleźć odpowiedni wierzchołek na liście i go stamtąd usunąć.

Implementacja
     Wymienione wcześniej wady i zalety list sąsiedztwa są w dużym stopniu zależne od sposobu implementacji i zastosowanej struktury danych. Postaram się przybliżyć wam dwa najpopularniejsze sposoby.

Sposób 1 - Tablica wskaźników
     Jest to zdecydowanie najgorsza metoda, jednak należy się z nią zapoznać. Polega na utworzeniu pewnej tablicy (lub vectora) o rozmiarze równym ilości wszystkich krawędzi. Nazwijmy ją A. W kolejnych pierwszych komórkach przechowywać będziemy sąsiadów wierzchołka numer 1. Następne komórki będą przechowywać sąsiadów wierzchołka 2, itd. Uzyskamy w ten sposób listę sąsiadów wszystkich wierzchołków. Jednak skąd będziemy wiedzieć w którym miejscu kończą się sąsiedzi jedynki, a zaczynają się sąsiedzi dwójki? Jest na to prosty sposób. Należy utworzyć drugą tablicę (nazwijmy ją W), która dla każdego wierzchołka będzie przechowywała informację o tym, w którym miejscu tablicy A zaczynają się jego sąsiedzi. Kończyć oczywiście będą się w miejscu wskazywanym przez następną komórkę tablicy W. Rysunek 4 przedstawia przykładowy graf oraz odpowiadające mu zawartości tablic A i W. Podstawową wadą takiego rozwiązania jest fakt, że gdybyśmy chcieli usunąć jakąś krawędź musieli byśmy przesunąć wszystkie następujące po niej wartości tablicy A o jedną komórkę w lewo oraz zmienić wartości wskaźników. Podobnie sprawa się ma z dodawaniem krawędzi.


Sposób 2 - Lista jednokierunkowa
     Sposób ten polega na utworzeniu dla każdego wierzchołka listy jednokierunkowej przechowującej jego sąsiadów. Lista taka to pewna struktura danych, która pozwala na na przyspieszenie pewnych operacji. Przykładowo: możemy usunąć dowolny element ze środka listy bez potrzeby przestawiania wszystkich jego następników. Przypominam, że jest to właśnie to co sprawiało, że poprzednia omówiona implementacja nie była zbyt dobra. Nie będę tłumaczył tutaj jak to dokładnie działa, gdyż wymagało by to szczegółowego omówienia list. Zachęcam jednak do przejrzenia innych źródeł i zapoznania się z tą strukturą danych.

I to by było na tyle...
     ...w tej części artykułu. W następnej części omówione zostaną dwa podstawowe algorytmy operujące na grafach: DFS i BFS. :)


Przejdź do następnej części
głosów: 5 | ocena: 8.19 oceń zasób | dodał: Platyna
Komentarze
Dodaj komentarz:
Treść:
Menu
Panel użytkownika
Jesteś niezalogowany!

Nie masz konta? Zarejestruj się
Użytkownicy on-line
0 użytkownik(ów) aktywny(ch) przez ostatnie 15 minut:
gości: 0, userów: 0, ukrytych: 0


5 użytkownik(ów) na gmczacie discord.com
Shoutbox
I am Lord (15:29, 26.09.17):
nie rozumiem
gnysek (11:57, 26.09.17):
Super, w GMS2 można sobie dowolnie stawiac rzeczy na layerach w runtime, ale w IDE już nie.
Threef (6:10, 26.09.17):
Pierwszy!
Gibki Kaktus (13:23, 24.09.17):
Poxi, ja pracuję w Deliveroo na rowerze xD Odwiedzasz czasem Londyn?
PoxiPol (11:21, 24.09.17):
Dzisiaj robie to tutaj takei o www.facebook.com/pappspizza
PoxiPol (11:20, 24.09.17):
Hah, w Anglii. Sprzedajem tutaj Polskiego Kebaba w bulce i inne, np grillowana kielbasa z frytkami, i schabowy.
Threef (9:44, 24.09.17):
Gdzie? Jaki? Bedziemy wspierać i prosić o kod na kolizję na opakowaniach
PoxiPol (7:05, 24.09.17):
Ja kupilem sobie prace. Jutro pierwszy dzien jako wlasniciel Takeawaya ;-;
Threef (19:32, 23.09.17):
Ja to zrozumiałem jakby Ranma nie chciał oddać domeny
PoxiPol (18:33, 23.09.17):
Nic przeciwko Ranmie ofc
PoxiPol (18:32, 23.09.17):
Ja to rozumiem jako dobra wiadomosc
Ranmus (18:23, 22.09.17):
Skąd ten smutek i zwątpienie?
gnysek (6:21, 22.09.17):
O, dzisiaj przychodzi mój hajs z googla, chyba mozna zacząć przenosić GMCLAN na "mój" serwer i przejąć od Ranmy domenę
Threef (19:56, 21.09.17):
No nie jest łatwo. Szczególnie jak dobra ma 24h
Ignatus (19:30, 21.09.17):
Ja tam mam bardziej nadzieję że zrobisz grę Threef Kiedy jakies premiery?
Threef (16:32, 21.09.17):
Mnie tak. Plus mam większą kontrolę. Mogę np robić warunki logiczne.
gnysek (15:54, 21.09.17):
Nie chciało mi się nigdy bawić w takie porównanie.
Threef (15:52, 21.09.17):
No i mam taką tablicę. Oczywiście mam tylko parametry jakie potrzebuję.
gnysek (8:53, 21.09.17):
W ogóle coś ma sie z particlami zmienić, nawet ma być dla nich layer w room editorze, wiec czuję edytor. Co do rysowania sprite w pętli - no to nie, bo mają więcej parametrów - to byś musiał zrobić sporą tablicę, żeby to odwzorować.
Threef (6:58, 21.09.17):
Czy particle są w końcu szybsze w GM:S2 od rysowania sprite w pętli? xD
gnysek (22:04, 20.09.17):
Znalazłem sposób na rysowanie spritów particli normalnie w draw: forum.yoyogames...s-sprites.34697
MaxGaming (16:35, 20.09.17):
jest ktoś kto mi by krótki refren angielski ze słuchu potrafił przetłumaczyć na już?
gnysek (13:37, 20.09.17):
Tu się akurat zgodzę
Ranmus (11:49, 20.09.17):
I bardzo dobrze, że nie ma dziwnych znaków. Same liczby i litery powinny być w nickach.
gnysek (11:14, 19.09.17):
Kodowanie... musiałbym przed każdym SQL do forum zmieniać kodowanie bazy, a potem je przywracać... do dupy z tym nowym forum, żaden to prezent
Uzjel (21:47, 18.09.17):
???
??? (21:38, 18.09.17):
;_;
I am vader (21:26, 18.09.17):
A, to YXE. Jego nick nie wyswietla sie poprawnie.
I am vader (21:25, 18.09.17):
Ciekawe kto to led.feen.us/lkx8xqvn.png
Wojo (10:59, 17.09.17):
chell śmiechłem
Chell (19:35, 13.09.17):
exp ty masz ojca poza kadrem albo cos?
exp (19:03, 13.09.17):
gmclan mnie wychował
exp (19:03, 13.09.17):
ehh
Wojo (12:50, 13.09.17):
Jak tak dalej pójdzie to będę musiał znaleźć realnych kolegów
Wojo (12:49, 13.09.17):
Tu nic nigdy nie działa. Cały czas stoimy w miejscu i nawer nie zapowiada się na korzystne zmiany
gnysek (9:41, 13.09.17):
Niestety, aby ten fix działał, trzeba wejść raz na forum i dopiero drugie wejście będzie OK (więc po fixie jeszcze raz mógł być problem)
gnysek (9:41, 13.09.17):
MaxGaming - bo dodałem usuwanie ciasteczek z domeny .forum.gmclan.org automatycznie. Czyli to jednak to było problemem.
SimianVirus7 (14:08, 12.09.17):
Dzięki
exp (11:15, 12.09.17):
możesz
SimianVirus7 (10:13, 12.09.17):
Tak
exp (9:50, 12.09.17):
czyli po prostu chcesz zrobić grę i wrzucić ją do internetu za darmo?
SimianVirus7 (9:03, 12.09.17):
Mi się śniło, że podpadłem rybnemu gangowi SpongeBoba ale nie po to się zalogowałem, żeby o tym powiedzieć mam pytanie, może dość głupie, ale prawo w Polsce też potrafi takie być. Czy jeśli chce swoją grę rozdawać za darmo i nie brać z tego absolutnie żadnych opłat (nawet z reklam), to mogę ją publicznie udostępniać? Skarbówka lub jakiś inny organ państwowy się do mnie nie przyczepi?
Chell (7:17, 12.09.17):
wpadłem tylko żeby napisać ze śniło mi się że zalogowałem się na 4tk
MaxGaming (17:49, 11.09.17):
Wreszcie mogę się zalogować. Odkąd weszło to nowe forum to nic nie działa jak powinno. Jak klikam w nowości z forum też raz mnie odsyła na główną forum a raz do tematu. PS mam dość proste wydaje mi się pytanie z MySQL którego ja osobiście znam póki co tylko absolutne podstawy. forum.gmclan.or...-i-subkategorii
doctor (18:49, 9.09.17):
Chociaż oficjalnie jest jakiś GDL, może w tym da się klepać (i 3 inne dokumentacje)
doctor (17:46, 9.09.17):
Przypomina nawet nieźle GM, niestety nie ma kodu (trzeba wyklikiwać jakby kod - czuję się jakbym grał w Patapony) - niby sporo funkcji jest (nawet 3D), ale wyklikiwać ...
doctor (17:45, 9.09.17):
Nowe konto xd Na stare wbić nie mogę :/ Jak ktoś szuka coś a'la Game Maker, czyli program do robienia upośledzonych gier to znalazłem GDevelop
Ignatus (20:21, 8.09.17):
Apropo Gnyska dziś czytałem temat o Almoraoczątek- we wstępnie jest "Gra ukaże się w drugiej połowie roku, na PC, a potem na iPada (możliwe, ze będzie to pierwsza produkcja w GameMaker:Studio 2)." A to temat z 2012. Gnysek jak długo trwały te beta testy GM2 ?
Threef (19:55, 8.09.17):
To że gnysek zrobił swego czasu grę o takiej nazwie.
Ankieta
» Jakiej wersji GameMakera głównie Używasz?
GameMaker: Studio 2
GameMaker: Studio
GameMaker 8.1 i starsze
Żadnej

GMCLAN to serwis o programie Game Maker i nie tylko.
Copyright © 2002-2017. GMCLAN.ORG
Wszelkie prawa zastrzeżone. Kopiowanie materiałów bez zgody redakcji zabronione!
© 2002-2017 Ranmus, © 2017 {=|=} fable_inside();

[ Czas generowania strony: 0.00974 sekund ] [ Liczba zapytań MySQL: 12 ]