qwertyuiopasdfghjklzxcvbnmqwerty uiopasdfghjklzxcvbnmqwertyuiopasd fghjklzxcvbnmqwertyuiopasdfghjklzx cvbnmqwertyuiopasdfghjklzxcvbnmq



Podobné dokumenty
Algoritmy na ohodnoceném grafu

Hledáme efektivní řešení úloh na grafu

Výhody a nevýhody jednotlivých reprezentací jsou shrnuty na konci kapitoly.

5 Orientované grafy, Toky v sítích

Úvod do teorie grafů

Obsah prezentace. Základní pojmy v teorii o grafech Úlohy a prohledávání grafů Hledání nejkratších cest

Prohledávání do šířky = algoritmus vlny

STROMOVE ALGORITMY Prohledavani do sirky (level-order) Po vodorovnejch carach fronta

3. Prohledávání grafů

Jan Březina. 7. března 2017

Grafy. RNDr. Petra Surynková, Ph.D. Univerzita Karlova v Praze Matematicko-fyzikální fakulta.

Základy informatiky. Teorie grafů. Zpracoval: Pavel Děrgel Úprava: Daniela Szturcová

Základy informatiky. 07 Teorie grafů. Kačmařík/Szturcová/Děrgel/Rapant

DUM 06 téma: Tvorba makra pomocí VBA

TGH05 - aplikace DFS, průchod do šířky

Algoritmizace prostorových úloh

PQ-stromy a rozpoznávání intervalových grafů v lineárním čase

Přehledy pro Tabulky Hlavním smyslem této nové agendy je jednoduché řazení, filtrování a seskupování dle libovolných sloupců.

Vzdálenost uzlů v neorientovaném grafu

Algoritmus pro hledání nejkratší cesty orientovaným grafem

Zdůvodněte, proč funkce n lg(n) roste alespoň stejně rychle nebo rychleji než než funkce lg(n!). Symbolem lg značíme logaritmus o základu 2.

07 Základní pojmy teorie grafů

TGH05 - aplikace DFS, průchod do šířky

Řešení: PŘENESVĚŽ (N, A, B, C) = přenes N disků z A na B pomocí C

Grafové algoritmy. Programovací techniky

4 Stromy a les. Definice a základní vlastnosti stromů. Kostry grafů a jejich počet.

Uživatelský manuál. Aplikace GraphViewer. Vytvořil: Viktor Dlouhý

Modely teorie grafů, min.kostra, max.tok, CPM, MPM, PERT

TGH09 - Barvení grafů

bfs, dfs, fronta, zásobník, prioritní fronta, halda

02. HODINA. 2.1 Typy souborů a objektů. 2.2 Ovládací prvky Label a TextBox

Dijkstrův algoritmus

Teorie grafů BR Solutions - Orličky Píta (Orličky 2010) Teorie grafů / 66

Grafové algoritmy. Programovací techniky

Grafy. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 13.

Binární vyhledávací stromy II

Stěžejní funkce MS Excel 2007/2010, jejich ovládání a možnosti využití

bfs, dfs, fronta, zásobník, prioritní fronta, halda

Barevnost grafů MFF UK

Vrcholová barevnost grafu

Semestrální práce 2 znakový strom

4 Pojem grafu, ve zkratce

Záznamník trasy. Michal Sluštík Y39PDA ČVUT, FEL, Popis aplikace. Specifikace požadavků

Intervalové stromy. Představme si, že máme posloupnost celých čísel p 0, p 1,... p N 1, se kterou budeme. 1. Změna jednoho čísla v posloupnosti.

H {{u, v} : u,v U u v }

Ukážeme si lineární algoritmus, který pro pevné k rozhodne, zda vstupní. stromový rozklad. Poznamenejme, že je-li k součástí vstupu, pak rozhodnout

Reliance 3 design OBSAH

Stromy, haldy, prioritní fronty

Použití dalších heuristik

Velmi stručný návod jak dostat data z Terminálu Bloomberg do R

Obecná informatika. Matematicko-fyzikální fakulta Univerzity Karlovy v Praze. Podzim 2012

Matematika III 10. přednáška Stromy a kostry

Úvodní list. Název školy Integrovaná střední škola stavební, České Budějovice, Nerudova 59 Číslo šablony/ číslo sady Poř. číslo v sadě 19 32/10

ALGORITMY A DATOVÉ STRUKTURY

4EK311 Operační výzkum. 5. Teorie grafů

Pokud nebude na příkazové řádce uveden právě jeden argument, vypište chybové hlášení a stručný

Postup pro zpracování kontrolního hlášení

Manuál k programu KaraokeEditor

State Space Search Step Run Editace úloh Task1 Task2 Init Clear Node Goal Add Shift Remove Add Node Goal Node Shift Remove, Add Node

1. Převeďte dané číslo do dvojkové, osmičkové a šestnáctkové soustavy: a) b)

Základní datové struktury III: Stromy, haldy

Kostry. 9. týden. Grafy. Marie Demlová (úpravy Matěj Dostál) 16. dubna 2019

Základní pojmy teorie grafů [Graph theory]

Graf. Uzly Lokality, servery Osoby fyzické i právní Informatické objekty... atd. Hrany Cesty, propojení Vztahy Informatické závislosti... atd.

8 Rovinnost a kreslení grafů

Zadání soutěžních úloh

Matice sousednosti NG

Lokality a uživatelé

Zadání soutěžních úloh

Teoretická informatika Tomáš Foltýnek Barvení grafů Platónská tělesa

Práce s programem IIS Ekonom

24 Uživatelské výběry

V každém kroku se a + b zmenší o min(a, b), tedy vždy alespoň o 1. Jestliže jsme na začátku dostali 2

Lineární spojový seznam (úvod do dynamických datových struktur)

Semestrální práce z KIV/PC. Kolja Matuševský (A14B0310P)

Spuštění a ukončení databázové aplikace Access

Programování 3. hodina. RNDr. Jan Lánský, Ph.D. Katedra informatiky a matematiky Fakulta ekonomických studií Vysoká škola finanční a správní 2015

Zpracování chybějících dat a dat mimo rozsah

GeoGebra známá i neznámá

Stromy. Jan Hnilica Počítačové modelování 14

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Dokument a jeho části oddíly, záhlaví, zápatí

GRAFY A GRAFOVÉ ALGORITMY

Kreslení grafů na plochy Tomáš Novotný

ZSF web a intranet manuál

Test prvočíselnosti. Úkol: otestovat dané číslo N, zda je prvočíslem

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Výroková a predikátová logika - III

ORIENTOVANÉ GRAFY, REPREZENTACE GRAFŮ

Obsah. 1.1 Práce se záznamy Stránka Dnes Kontakt se zákazníkem... 5

Maturitní téma: Programovací jazyk JAVA

Gymnázium Vysoké Mýto nám. Vaňorného 163, Vysoké Mýto

Implementace LL(1) překladů

1. Základní pojmy, používané v tomto manuálu. 2. Stránky

Cílem kapitoly je seznámit studenta se seznamem a stromem. Jejich konstrukci, užití a základní vlastnosti.

fakulty MENDELU v Brně (LDF) s ohledem na disciplíny společného základu (reg. č. CZ.1.07/2.2.00/28.

Dynamické datové struktury I.

8 Přednáška z

Popis ovládání. Po přihlášení do aplikace se objeví navigátor. Navigátor je stromově seřazen a slouží pro přístup ke všem oknům celé aplikace.

Úvod do informatiky. Miroslav Kolařík

Transkript:

qwertyuiopasdfghjklzxcvbnmqwerty uiopasdfghjklzxcvbnmqwertyuiopasd fghjklzxcvbnmqwertyuiopasdfghjklzx cvbnmqwertyuiopasdfghjklzxcvbnmq APLIKACE GRAFY Dokumentace wertyuiopasdfghjklzxcvbnmqwertyui Jan Škvařil opasdfghjklzxcvbnmqwertyuiopasdfg hjklzxcvbnmqwertyuiopasdfghjklzxc vbnmqwertyuiopasdfghjklzxcvbnmq wertyuiopasdfghjklzxcvbnmqwertyui opasdfghjklzxcvbnmqwertyuiopasdfg hjklzxcvbnmqwertyuiopasdfghjklzxc vbnmqwertyuiopasdfghjklzxcvbnmq wertyuiopasdfghjklzxcvbnmqwertyui

OBSAH DOKUMENTU Zadání... 3 Program... 3 Reprezentace grafu... 3 Fronta a halda... 4 Zvolený algoritmus... 5 Počet nejkratších cest mezi dvěma vrcholy... 5 Hledání kružnice v grafu... 6 Hledání minimální kostry... 7 Topologické třídění... 8 Barvení rovinného grafu pěti barvami... 9 Reprezentace vstupních a výstupních dat aneb nápověda... 11 Formát grafů uložených v souboru... 16 Sada testovacích příkladů... 16 [2]

ZADÁNÍ Zadáním bylo vytvořit aplikaci, která bude umět zacházet s grafy a bude implementovat některé ze základních grafových algoritmů: hledání počtu nejkratších cest mezi dvěma vrcholy, hledání kružnice v grafu, hledání minimální kostry grafu a topologické třídění grafu. Dále má tato aplikace umět ukládat graf ve vhodném formátu do souboru a zpětně jej ze souboru načíst. Aplikace se nakonec poněkud rozrostla: umí pracovat jak s orientovanými, tak s neorientovanými grafy, načtený graf je možno editovat lze přidávat či odebírat vrcholy či hrany, každému vrcholu a každé hraně je možno přiřadit určitou váhu a tu posléze upravit. K implementovaným grafovým algoritmům přibylo ještě obarvení rovinného grafu pěti barvami. PROGRAM Jedná se o klasickou WinForms aplikaci vytvořenou v prostředí.net v programovacím jazyce C#. Funkce Main() ve třídě Program tedy pouze vytvoří nový hlavní formulář, který obsahuje komponenty sloužící ke komunikaci s uživatelem (menu, tlačítka atp.) a tyto komponenty umí obsloužit (a to i tak, že úkol deleguje nějakému jinému objektu). Exsitují ještě další, jednodušší formuláře, které slouží k vypsání nápovědy k aplikaci, případně k zadání vstupních hodnot od uživatele. Tyto formuláře jsou statické a všechny jsou potomky třídy NonResizableForm. Na této třídě je zajímavé pouze to, jakým způsobem je zaručeno, že od každého potomka této třídy bude najednou vytvořena maximálně jedna instance: abstraktní třída NonResizableForm si drží statickou proměnnou opened, do které se při otevření nového okna přičte hodnota identifikátoru daného typu formuláře. Tyto identifikátory jsou mocninou čísla 2 z bitové reprezentace proměnné opened můžeme tedy zrekonstruovat, která okna jsou otevřena (pomocí operátoru logického and [&]). REPREZENTACE GRAFU Grafy jsou v programu reprezentovány následujícím způsobem: hlavní okno aplikace obsahuje jednu instanci třídy Graph, která obsahuje seznam vrcholů grafu. Každý vrchol je [3]

instancí třídy Vertex a drží si informaci o tom, jaké je jeho číslo, na jaké pozici je aktuálně na obrazovce vykreslena a jaká je jeho barva a váha. Především si ale udržuje seznam hran, které z něj vycházejí. Neorientované grafy jsou tedy reprezentovány stejným způsobem jako orientované. Jediný rozdíl je v tom, že neorientovaná hrana je reprezentována dvěma hranami orientovanými. Každá hrana v grafu je instancí třídy Edge a drží si informaci o tom, do kterého vrcholu vede. To, z kterého vrcholu vede, není podstatné, tuto informaci známe, protože hranu musí obsahovat nějaký vrchol, a z tohoto vrcholu tedy hrana vychází. Hrany si také udržují informaci o tom, jaká je jejich aktuální barva a jakou mají váhu. Všechny vlastnosti této třídy jsou soukromé a třída k nim poskytuje rozhraní. Stejným způsobem je navržena třída Vertex, která má ale navíc několik veřejných proměnných, kam si mohou příslušné algoritmy ukládat hodnoty, které potřebují k výpočtu. Návrh je tedy takový, že existuje nějaký graf, který je obsažen v okně aplikace a zde je vykreslen. Mimo tento graf jsou algoritmy, které s ním něco udělají (např. jej obarví), a graf jim k tomu poskytuje podporu v podobě rozhraní. Třída Vertex má navrženy metody pro přidávání a odebírání hran; tím je zajištěno, že žádná hrana nebude v grafu obsažena vícektát a že nám v grafu nevzniknou smyčky. Podobným způsobem je realizována třída Graph, která umožňuje pohodlné přidávání a odebírání vrcholů z grafu, popř. i hran. Seznamy vrcholů i hran jsou udržovány setříděné (třída SortedList). Tím je zajištěno rychlé vyhledávání vrhcolů či hran podle jejich identifikačních čísel. FRONTA A HALDA Některé grafové algoritmy potřebují ke své práci frontu či haldu. Fronta je navržena jako generická třída (v C++ bychom řekli šablona), čímž je zajištěno, že si můžeme určit, jakého typu budou objekty, které v ní budeme uchovávat. Fronta má klasické operace Push() a Pop() pro přidání prvku do fronty a pro jeho odebrání. Halda na rozdíl od fronty není generická a je v ní možno uchovávat pouze vrcholy. Ty jsou v haldě seřazeny podle svého výstupního stupně, čehož je využito v algoritmu barvení [4]

rovinného grafu pěti barvami. Halda má také klasické operace: Insert() a ExtractMin() pro přidání prvku do haldy a pro odebrání vrcholu s minimálním výstupním stupněm. ZVOLENÝ ALGORITMUS Grafových algoritmů je v aplikaci implementováno celkem pět a všechny si zde postupně rozebereme, neboť se jedná o algoritmicky nejdůležitější část programu. Kromě těchto algoritmů se zmíním pouze o tom, jakým způsobem funguje klikání na vrcholy ve vykresleném grafu (tedy přidávání a odebírání hran či přidávání vrcholů). K tomuto účelu jsou využity metody OnMouseDown a OnMouseUp, kdy podle souřadnic, kam bylo kliknuto, zjistíme, jestli se tam nachází nějaký vykreslený vrchol. Zjištění probíhá v lineárním čase vzhledem k počtu vrcholů (kterých není nikdy vykresleno více než 200) projdeme všechny vrcholy a zjistíme, jestli je vzdálenost bodu, kam jsme klikli myší od středu daného vrcholu, menší než poloměr tohoto vrchou, který činí 6px. Vzdálenost mezi dvěma body počítáme jako klasickou vzdálenost v eukleidovském dvourozměrném prostoru. V popisu všech algoritmů ještě předem označme písmenem N počet vrcholů grafu a písmenem M počet hran grafu. POČET NEJKRATŠÍCH CEST MEZI DVĚMA VRCHOLY Ve fázi inicializace si algoritmus v lineárním čase nastaví proměnné u vrcholů na výchozí hodnotu, vytvoří si novou frontu a umístí do ní vrchol, ze kterého hledáme počet nejkratších cest. Poté následuje fáze, ve které procházíme graf, a to tak dlouho, dokud se frontě nachází nějaký vrchol. Ve smyčce vždy vyzvedneme z fronty vrchol, který v ní čeká jako první, a označíme jej jako dokončený, čímž je zaručeno, že se do fronty již znovu nedostane a že algoritmus vždy skončí, neboť má konečný počet vrcholů (shora omezený konstantou 20000). U každého vrcholu, který jsme právě vyzvedli z fronty, projdeme všechny jeho hrany a podíváme se na vrcholy, kam tyto hrany vedou. Pokud hrana vede do vrcholu, kam ještě [5]

nevede žádná nejkratší cesta, nebo pokud jsme našli novou nejkratší cestu, přenastavíme u vrcholu, kam hrana vede, počet nejkratších cest takto: nechť aktuální hrana vede z vrcholu u do vrcholu v, pak nastavíme vrcholu v počet nejkratších cest jako v.pathcounter = v.pathcounter + u.pathcounter. Technicky se tedy jedná o prohledávání do šířky. Počet nejkratších cest nakonec nalzneme u koncového vrcholu v jeho proměnné pathcounter. Pokud žádná takováto cesta neexistuje, je proměnná správně nastavena na 0. Díky tomu, že si u každého vrcholu udržujeme seznam vrcholů, z kterých jsme do něj přišli nejkratší cestou, můžeme nakonec zrekostruovat jednu z nejkratších cest a vyznačit ji v grafu uživateli. Poznámka: Z důvodu hrozby přetečení datového typu Int32 není počet nejkratších cest vypisován přesně; jedná se o zbytek po dělení velkým číslem. Časová složitost algoritmu je O(N + M). HLEDÁNÍ KRUŽNICE V GRAFU V tomto algoritmu využijeme prohledávání do hloubky budeme prohledávat daný graf a u každého vrcholu si budeme držet informaci, kdy jsme do něj vstoupili a kdy jsme z něj vystoupili. K tomu využijeme statickou proměnnou timer, kterou budeme postupně zvyšovat o 1 a časy si budeme do vrcholů zaznamenávat. Prohledávání do hloubky zde není realizováno klasickou rekurzivní metodou, ale je nahrazeno cyklem se zásobníkem. Důvod je ten, že u velkých grafů se může stát, že se vyčerpá kapacita systémového zásobníku. Po vynoření z této metody tedy máme u každého vrcholu zaznamenán určitý časový interval. Tím, jak jsme procházeli graf, jsme vlastně vytvářeli určitý strom, který ovšem může obsahovat tzv. příčné, dopředné či zpětné hrany. A právě díky této znalosti můžeme poznat, jestli graf obsahuje kružnici. Obsahuje ji právě tehdy, když tento graf DFS průchodu obsahuje zpětnou hranu a tu poznáme díky zaznamenaným časům vstupu a výstupu u každého vrcholu. Konkrétně poznáme zpětnou hranu tak, že čas příchodu do vrcholu, odkud hrana vede, je větší než čas příchodu do vrcholu, kam hrana vede, a zároveň je čas odchodu z vrcholu, [6]

odkud hrana vede, menší než čas odchodu z vrcholu, kam hrana vede. Takto si poznamenáme všechny zpětné hrany. Poté tyto zpětné hrany projdeme ještě totiž nemáme vyhráno, protože musíme rozlišit případ, kdy se jedná o orientovaný graf (poté nás zajímá i kružnice na dvou vrcholech), od případu, kdy se jedná o neorientovaný graf (poté požadujeme, aby měla kružnice alespoň tři vrcholy). U každé zpětné hrany tedy najdeme nejdelší cestu mezi těmito dvěma vrcholy a podíváme se, zdali nalezená kružnice (se zpětnou hranou tato cesta určitě tvoří kružnici) vyhovuje našim požadavkům. Pokud ano, pak tuto kružnici algoritmus v grafu označí. Algoritmus by měl pracovat v čase O(N + M), avšak konstanty jsou zde trochu větší, protože musíme celý graf projít vícekrát. HLEDÁNÍ MINIMÁLNÍ KOSTRY K hledání minimální kostry je implementován Kruskalův algoritmus, kde požadujeme, aby se jednalo o neorientovaný souvislý graf. Tyto dvě podmínky tedy algoritmus na začátku otestuje. V tomto algoritmu se hodí udržovat si hrany jako dvojice vrcholů, využijeme tedy třídu VertexDouble. Na začátku si vyrobíme seznam hran setříděných dle jejich váhy. Kruskalův algoritmus ale předpokládá, že každé dvě hrany mají rozdílnou váhu. Protože máme váhy hran celočíselné, můžeme z nich udělat váhy reálné, a to tak, že pokud najdeme nějaké dvě hrany se shodnou váhou, pak k jedné z nich přičteme malou reálnou konstantu, čímž můžeme hrany jednoznačně uspořádat. Na začátku si vyrobíme pomocný graf, který bude obsahovat pouze vrcholy našeho prohledávaného grafu; technicky se tedy jedná o les. Samotný algoritmus poté dělá toto: projdeme seznam hran setříděných dle váhy a u každé se podíváme na to, zda by jejím přidáním do grafu vznikla kružnice. Pokud by kružnice nevznikla, přidáme ji. Kontrolu, jestli by vznikla kružnice, nám zajišťuje metoda TreeFind, která zjistí, zda jsou v našem pomocném grafu vrcholy, mezi kterými vede tato hrana, ve stejné komponentě souvislosti. Pokud ano, pak by tato hrana vytvořila kružnici. Pokud ne, pak tuto hranu [7]

přidáme do kostry a sloučíme dvě komponenty souvislosti v pomocném grafu do jedné. Nakonec minimální kostru v grafu vyznačíme. Jak vypadají tyto komponenty souvislotsti v našem pomocném grafu? Každou komponentu si pamatujeme jako zakořeněný strom, v němž si každý vrchol pamatuje svého otce. Metoda TreeFind tedy najde kořeny komponent, ve kterých se nacházejí dané dva vrcholy, a tyto dva kořeny porovná. Pokud jsou shodné, pak se vrcholy nacházejí v téže komponentě. Každý kořen si ještě pamatuje hloubku svého stromu. Pokud tedy spojujeme dva stromy do jednoho, podíváme se na jejich hloubky a zařadíme mělčí strom pod hlubší. Pokud jsou jejich výšky shodné, je to jedno, ale musíme novému kořeni zvýšit výšku o 1. Vzhledem k maximálně logaritmické výšce pěstovaných stromů funguje algoritmus celkově v čase O(M.logN). TOPOLOGICKÉ TŘÍDĚNÍ Topologické třídění lze provést pouze na orientovaných grafech bez kružnic algoritmus tedy na začátku zkontroluje, jestli zadaný graf splňuje tyto dvě podmínky. Využijeme faktu, že v takovém grafu musí existovat alespoň jeden vrchol se vstupním stupněm 0 (jedná se totiž o les). Na začátku tedy spočítáme u každého vrcholu jeho vstupní stupeň a najdeme vrcholy se vstupním stupněm 0 a ty přidáme do fronty. Následně procházíme celý graf, dokud není fronta prázdná, a to tak, že vždy vyzvedneme vrchol fronty, označíme jej jako dokončený, projdeme všechny jeho hrany a u vrcholů, kam vedou, snížíme vstupní stupeň o 1. Jedná se [8]

tedy o odtržení vrcholu od grafu; tento vrchol přidáme na konec našeho topologického třídění grafu. Následně do fronty přidáme všechny vrcholy, které mají nově vstupní stupeň roven 0 a zárověň jsme je ještě neměli ve frontě. Tím je zaručeno, že se na každý vrchol podíváme právě jednou a algoritmus skončí v čase O(N + M). Nakonec dané topologické třídění vypíšeme. BARVENÍ GRAFU PĚTI BARVAMI Jedná se o nejsložitější implementovaný algoritmus. Na vstupu předpokládá neorientovaný graf, který má maximálně 3N 6 hran, tedy třídu grafů větší než jsou rovinné grafy, neboť rovinné grafy musí splňovat tuto podmínku, avšak mohou ji splňovat i některé grafy nerovinné. Předpokládejme nyní, že algoritmus dostane na vstupu skutečně rovinný graf, který umí obarvit pěti barvami. Pokud na vstupu dostane nerovinný graf a nepodaří se jej obarvit, pak o této skutečnosti informuje. Algoritmus funguje přesně podle důkazu věty o pěti barvách až na jednu odchylku, o které se zmíním později. Nejdříve vytvoříme haldu vrcholů, kde bude v jejím kořeni vždy vrchol s minimálním výstupním stupněm. Z rovinnosti grafu plyne, že tento vrchol bude mít stupeň menší nebo roven číslu 5 (aneb v každém rovinném grafu extistuje vrchol stupně nejvýše 5). Důkaz věty o pěti barvách se provádí indukcí toho je zde využito a algoritmus je rekurzivní. Nejedná se o přímou rekurzi, nýbrž o cyklus se zásobníkem, což je v důsledku totéž, uvažujme však, jako by byl algoritmus implementován rekurzivně. Při každém zavolání rekurzivní metody se zkontroluje, jestli je v haldě nanejvýš 5 vrcholů, které případně můžeme jednoduše obarvit pěti barvami každému vrcholu přiřadíme jednu z pěti barev, kterými graf barvíme. Jestliže je v haldě, která představuje aktuálně barvený graf, více než 5 vrcholů, pak z ní odebereme vrchol, který je aktuálně v kořeni (ten s nejnižším stupněm), a odtrhneme jej od grafu, což technicky znamená, že všem jeho sousedům v haldě snížíme stupeň o jedna a vzniklou strukturu případně přeorganizujeme tak, aby se opět jednalo o haldu. U vrcholu, který jsme odebrali z haldy, si poznamenáme, že jsme jej již zpracovali. [9]

Rovinný graf, od kterého jsme odtrhli vrchol, je opět rovinný, a tím pádem v něm opět musí existovat vrchol stupně nanejvýš pět, který najdeme v kořeni haldy. Tím pádem se můžeme rekurzivně zavolat a celou proceduru zopakovat, až se dostaneme k triviálnímu případu, kdy nám zbude graf o pěti vrcholech, který umíme vyřešit. Z toho, že postupně odtrháváme vrcholy z grafu (technicky vzato snižujeme jejich stupeň v haldě), plyne, že náš aktuálně odebraný vrchol z haldy má stupeň nanejvýš 5. Označme tento vrchol písmenem v. Nyní víme, že po rekurzivním zavolání má náš graf G-v z indukčního předpokladu nějaké korektní obarvení pěti barvami. Počet sousedů každého vrcholu po odebrání z haldy si u něj udržujeme v proměnné OutputDeg. Důležité je, že tato proměnná se po zavolání rekurzivní metody již nezmění, neboť jsme si u vrcholu poznamenali, že jsme jej již navštívili, a u takových vrcholů stupeň již nesnižujeme. Předtím, než se ponoříme do rekurze, si ještě u vrcholu vytvoříme seznam jeho sousedů (kterých musí být maximálně 5). Po vynoření z rekurze u něj tedy máme poznamenán jeho stupeň a seznam jeho sousedů. Pokud má vrchol v stupeň ostře menší než 5 (tj. má maximálně 4 sousedy), pak jej obarvíme zbývající barvou. Pokud má přesně pět sousedů a nepodařilo se nám najít barvu, kterou bychom mohli náš vrchol v obarvit (tedy jeho sousední vrcholy mají navzájem různé barvy), pak budeme muset graf přebarvit. V důkazu věty o pěti barvách využíváme toho, že máme konkrétní rovinné nakreslení grafu G, a vezmeme protilehlé dvojice sousedů vrcholu v. Toho zde využít nemůžeme, a budeme tedy muset postupně projít všech 10 dvojic sousedů vrcholu v. Pro každou z nich otestujeme, jestli v grafu G-v mezi nimi vede cesta tvořená pouze vrcholy, které používají barvy těchto dvou vrcholů. Z těchto deseti dvojic musí existovat alespoň jedna, která není takovouto cestou spojena, což plyne z rovinnosti grafu. Při hledání této dvojice vrcholů (označme si tyto dva vrcholy jako u a t) si vždy vytvoříme množinu vrcholů D, které jsou dosažitelné z vrcholu u právě těmito dvoubarevnými cestami. Speciálně pokud se v této množině nachází i vrchol t, pak metoda pro hledání této dvojice vrací true, neboť mezi vrcholy u a t tato dvoubarevná cesta existuje. Jakmile tedy najdeme [10]

dvojici vrcholů u a t, mezi nimiž tato cesta neexistuje, pak v množině D přebarvíme vrcholy obarvené barvou příslušnou vrcholu u na barvu příslušnou vrcholu t a opačně. Jinými slovy v této množině vrcholů prohodíme vrcholům jejich barvy. Toto je určitě opět korektní obarvení grafu G-v, avšak vrcholy u a t mají nyní stejnou barvu, a to tu, kterou měl původně vrchol t. Můžeme tedy náš vrchol v obarvit barvou, kterou měl původně vrchol u. Protože je stejný postup aplikován na každý vrchol grafu G, znamená to, že tento algoritmus vydá korektní obarvení rovinného grafu pěti barvami. Aplikace umí toto obarvení přímo vykreslit a v případě velkých grafů nabídne uživateli možnost toto obarvení uložit do nějakého souboru. Časová složitost je O(N 2 ). REPREZENTACE VSTUPNÍCH A VÝSTUPNÍCH DAT ANEB NÁPOVĚDA Po spuštění aplikace Grafy se nám zobrazí úvodní uvítací obazovka. Zde můžeme buď vytvořit zcela nový graf, načíst graf ze specifikovaného souboru či zobrazit uživatelskou nápovědu aplikace, kde se můžeme seznámit s její základní funkčností. Nový graf můžeme vytvořit buď orientovaný, nebo neorientovaný. Klávesovou zkratkou CTRL+N nebo kliknutím na tlačítko Nový graf se vždy vytvoří neorientovaný graf. Orientovaný graf lze tedy vytvořit pouze výběrem této možnosti z horního menu. [11]

Kliknutím na tlačítko Otevřít graf (nebo stisknutím klávesové zkratky CTRL+O nebo výběrem položky Soubor > Otevřít z vrchního menu) můžeme načíst graf, který máme uložený v nějakém souboru. Tento soubor musí mít určitý formát, který je popsán níže, avšak jedná-li se o soubor, který byl vytvořen aplikací Grafy (uložením nějakého grafu např. klávesovou zkratkou CTRL+S), pak tento formát určitě splňuje. V menu Upravit se můžeme přepnout do jednoho z šesti možných módů aplikace (kromě módu standardního). Můžeme do grafu přidávat vrcholy či hrany, odebírat vrcholy či hrany nebo upravit váhu vrcholů či hran. Po vytvoření nového grafu se automaticky zapne mód přidávání vrcholů. Nový vrchol přidáme tak, že (pokud jsme v módu přidávání vrcholů) klikneme myší někam, kde zatím není vykreslen žádný vrchol, a tam se vrchol objeví. Novou hranu přidáme tak, že klikneme postupně na dva vrcholy, které má nová hrana spojovat. Tyto vrcholy se budou postupně obarvovat zeleně. Odebrání vrcholu či hrany z grafu se provádí obdobným postupem musíme být samozřejmě v příslušném módu aplikace. Při odebírání hran se budou vrcholy, které tato hrana tvoří, obarvovat červeně. [12]

Úprava vah vrcholů či hran je založena na stejném principu tedy vybereme vrchol či hranu a do nově otevřeného okna vepíšeme novou váhu. Váha musí být zadána jako přirozené číslo (nulu zde za přirozené číslo nepovažujeme). V menu zobrazit si můžeme vybrat, jestli chceme zobrazit váhy vrcholů, váhy hran či čísla vrcholů. Příslušné ohodnocení či číslo vrcholu se u něj následně objeví, ohodnocení hrany se objeví v jejím středu. Pokud máme zapnuto zobrazování vah vrcholů i jejich čísel, vypíše se u vrcholu nejdříve jeho číslo a za dvojtečkou jeho váha. [13]

Na načtený graf je možno aplikovat jeden z pěti algoritmů přístupných v menu Graf. Pokud je graf vykreslitelný (tedy má nejvýše 200 vrcholů), pak algoritmus pro počet nejkratších cest v grafu jednu z těchto cest vyznačí. Algoritmus pro hledání kružnice ji v grafu rovněž vyznačí a algoritmus pro hledání minimální kostry ji také vykreslí. Všechna tato vyznačení jsou provedena modrou barvou, vyznačené hrany jsou vyobrazeny tučně a modře. Pokud je graf příliš velký, pak po dokončení algoritmu hledání kružnice nabídne aplikce možnost uložit výsledky jeho práce do souboru. V tomto souboru je na každém řádku napsáno číslo vrcholu, který je v kružnici obsažen, a mezerou je odděleno číslo vrcholu, do kterého z něj vede hrana. Pokud je tento soubor otevřen v aplikaci Grafy, pak je skutečně vykreslena kružnice. Obdobně je pro příliš velké grafy nabídnuto uživateli uložit výsledky práce algoritmu hledání minimální kostry. Formát tohoto souboru je takový, že na každém řádku je uložena jedna hrana grafu, která je obsažena v minimální kostře. Tato hrana je zapsána jako dvojice čísel vrcholů ve složených závorkách a za znakem x pak následuje váha této hrany. Výstup topologického třídění grafu je vždy seznam čísel vrcholů oddělených mezerami. Tyto vrcholy čteny zleva doprava tvoří topologické uspořádání grafu, tedy vrchol více vlevo je v daném topologickém uspořádání menší než vrchol více vpravo. [14]

Pokud je v topologickém uspořádání příliš mnoho vrcholů (více než 200), pak je uživateli nabídkuto uložit toto uspořádání do souboru. Formát tohoto souboru je shodný s formátem topologického třídění vypsaného přímo na obrazovku v případě menších grafů. Obarvení rovinného grafu probíhá u vykreslitelných grafů (méně než 200 vrcholů) přímo, u větších grafů je nabídnuto uložit toto obarvení do souboru. V tomto souboru se na každém řádku nachází číslo jednoho vrcholu a za znakem x následuje číslo barvy, kterou je obarven. [15]

Tento soubor je možno následně v apliakci Grafy otevřít a čísla barev (od 1 do 5) budou interpretována jako váhy vrcholů. FORMÁT GRAFŮ ULOŽENÝCH V SOUBORU Soubor, ve kterém je uložen nějaký graf, musí splňovat následující specifikaci: na každém neprázdném řádku, který není komentářem, je uloženo číslo vrcholu a za mezerou následuje mezerami oddělený seznam čísel vrcholů, do kterých z tohoto vrcholu vedou hrany. Za každým číslem vrcholu uloženým v souboru může následovat znak x, oddělující jeho váhu; stejným způsobem lze uložit váhy jednotlivých hran, opět pomocí znaku x, oddělujícího váhu dané hrany. V souboru je možno používat komentáře komentář je řádek, který začíná znakem # ; tyto řádky jsou při načítání grafu ignorovány. Avšak pozor: po zpětném uložení grafu jsou všechny komentáře, které v souboru původně byly, přesunuty na začátek tohoto souboru. Po komentářích ještě může následovat řádek, který specifikuje, jestli se jedná o orientovaný nebo neorientovaný graf. Pokud je na řádku napsáno slovo normal, jedná se o neorientovaný graf, pokud je na řádku napsáno orientated, jedná se o orientovaný graf. Výchozí hodnota je normal. Pozor, tato specifikace musí předcházet všem v souboru specifikovaným vrcholům a musí být napsána malými písmeny, jinak na ni nebude brán zřetel. Graf bude považován za neorientovaný a aplikace ohlásí chybu, že formát souboru je chybný (avšak graf načte). Za seznamem hran na řádku příslušícím určitému vrcholu mohou ještě následovat středníkem oddělená dvě čísla, která specifikují pozici vrcholu v aplikaci (x-ová a y-ová souřadnice). Takto je možno do souboru společně s grafem uložit i jeho konkrétní nakreslení. SADA TESTOVACÍCH PŘÍKLADŮ Sada testovacích příkladů je v adresáři Testovaci-priklady. U každého zde uloženého grafu je v komentáři na začátku souboru popsáno, o jaký graf se jedná. Tyto testovací příklady mohou také sloužit jako ukázka formátu grafů uložených v souboru. [16]