Kruskalův algoritmus - implementace

  • View
    1.065

  • Download
    3

  • Category

    Science

Preview:

Citation preview

Ivo Kostecký, kos0148projekt předmětu Matematika pro zpracování znalostí na VŠB-TUO

Implementace:

Kruskalův algoritmus

V ohodnocených grafech určete všechny nejlevnější kostry grafu pomocí Kruskalova algoritmu.

Zadání

Neumím si přečíst zadání…

V ohodnocených grafech určete všechny nejlevnější kostry grafu pomocí Kruskalova algoritmu.

…zpracoval jsem:V ohodnocených grafech jsem určil první nejlevnější kostru grafu pomocí Kruskalova algoritmu.

Problém

Kostra grafuV teorii grafů je kostra souvislého grafu G takový podgraf souvislého grafu G na množině všech jeho vrcholů, který je stromem.

Pojmy

Kdy má smysl hledat kostru?• Graf je souvislý (projekt umí najít i více koster ve více

grafech, pokud je zdroj nespojitý)

• Graf je neorientovaný (případnou orientaci zahazuje)

• Graf je vážený (hrany mají kladné ohodnocení)

Pojmy

Proč hledat minimální kostru v grafových úlohách? 

Motivace

Návrh elektrické sítě

Máme k dispozici seznam odběrných míst a chceme je propojit tak, abychom využili co nejmenší množství drátů. 

Proč hledat minimální kostru v grafových úlohách? 

Motivace

Smyčky v počítačových sítích

Spanning Tree Protocol (v překladu protokol kostry grafu) je v informatice název pro síťový protokol, který v ethernetových sítích odstraňuje smyčky na druhé vrstvě ISO/OSI modelu. 

Princip algoritmu

Myšlenka implementace algoritmu1.Seřadit hrany podle ceny od nejmenší po největší

2.Nastavit všem vrcholům stejnou doménu značící nezařazenost

3.Procházet všechny hrany a u jejich vrcholů sledovat, zda splňují podmínky a zpracovat je (viz dále) • pokud jsou oba vrcholy nové

• pokud je první vrchol nový a druhý již existuje

• pokud je druhý vrchol nový a první již existuje

• pokud již existují oba dva a mají stejné domény

• pokud již existují oba dva a mají různé domény

Výsledkem je • seznam hran splňující podmínku acykličnosti a nejmenší metriky• seznam vrcholů s doménami podle grafových souvislostí C#

Datové struktury 1

C#

Vrchol

Hrana

Graf

Implementace algoritmupublic List<Graph> Kruskal() {

List<Graph> grafy = new List<Graph>(); //seznam koster nalezených v grafechList<Vertex> pouzitevrcholy = new List<Vertex>(); //pouzite vrcholy jednotlivych grafuList<Edge> pouzitehrany = new List<Edge>(); //pouzite hrany jednotlivych grafuDictionary<int, List<Vertex>> domains = new Dictionary<int, List<Vertex>>(); //seznam vrcholů roztřízený podle

domén

Seznamhran.Sort(new EdgeComparer()); //serazeni hran podle ceny

foreach (Vertex v in Seznamvrcholu) //reset domén při opakovaném běhu {

v.Domain = -1;}int domainCounter = 0; //čítač nesouvislých domén

foreach (Edge hrana in Seznamhran) //pridavani hran do komponent{

//viz podmínky dříve, viz implementace dále}…

C#

Všimněte si využití existujících struktur:

List<Edge> pouzitehrany = new List<Edge>();Dictionary<int, List<Vertex>> domains = new Dictionary<int, List<Vertex>>();

Seznam má časovou složitost O(n) – lineárníSlovník má časovou složitost O(1) - konstatní

Výhodné pro rychlý běh programu!

Datové struktury 2

„kruskalizace“ hran a vrcholů

C#

pokud ani jeden vrchol ještě nebyl zpracován

*Pardon, momentálně trpím obdobím psaním komentářů ve dvou jazycích.

„kruskalizace“ hran a vrcholů

C#

pokud byl dosud zpracován pouze jeden vrchol z hrany

„kruskalizace“ hran a vrcholů

C#

pokud již existují oba dva a mají stejné domény

pokud již existují oba dva a mají různé domény Dochází ke spojování dvou domén do sebe

Hrana je duplicitní nebo by vytvořila cyklus, proto se nepřidá

int domainSmaller = (domains[1.].Count < domains[2.].Count) ? 1. : 2.; //určí ve které doméně je méně vrcholůint domainGreater = (domains[1.].Count >= domains[2.].Count) ? 1. : 2.; //určí ve které doméně je více vrcholů

foreach (Vertex bod in domains[domainSmaller]){ bod.Domain = domainGreater; } //rename domain in transfered vertexes

domains[domainGreater].AddRange(domains[domainSmaller]); //movedomains[domainSmaller].Clear(); //remove unused

pouzitehrany.Add(hrana); //finally add edge

Pokračování implementace algoritmu…//pro graf potřebuji mít seznamy hran a vrcholů v samostatných listech, vytvořím si předobraz (zatím je mám všechnyDictionary<int, List<Vertex>> domenovevrcholy = new Dictionary<int, List<Vertex>>(); Dictionary<int, List<Edge>> domenovehrany = new Dictionary<int, List<Edge>>();

//inicialializace seznamů podle příslušnosti k doménámforeach (int i in domains.Keys){

if (domains[i].Count == 0){ continue; }domenovevrcholy.Add(i, new List<Vertex>());domenovehrany.Add(i, new List<Edge>());

}

//rozřazení vrcholů podle domén do slovníku, klíčem je ID doményforeach (Vertex vrchol in pouzitevrcholy){

domenovevrcholy[vrchol.Domain].Add(vrchol); }…

C#

Dokončení implementace algoritmu…//rozřazení hran podle domén do slovníku, klíčem je ID domény prvního vrcholuforeach (Edge hrana in pouzitehrany){

if (hrana.Vertex1.Domain != hrana.Vertex2.Domain) //pouze pokud by něco dříve selhalo { continue; }

domenovehrany[hrana.Vertex1.Domain].Add(hrana);}

//podle toho, kolik skupin vrcholů je, tolik je nesouvislých grafů, ty je třeba vytvořitforeach (int i in domenovevrcholy.Keys){

grafy.Add(new Graph(domenovevrcholy[i], domenovehrany[i]));}

return grafy; //konec kruskalova algoritmu} C#

Výsledné GUI

Vyhodnocení• Algoritmus již dle mého nelze jednoduše urychlit

• Metoda má na délku běhu celé úlohy minimální význam (načítání vstupních dat je mnohem pomalejší)

• CSV ve formátu, který popisuje tabulka• Očekáván velký rozsah (zbytečně)• Nedefinovány platné vstupy

Způsob vyhodnocení

Zdroj dat

• Korektnost výstupu (nedosažena)• délka běhu v závislosti na vstupních datech

Možnost opravy 1Najde další nejlevnější kostry pomocí Kruskalova algoritmu

Nový proces (fork) si zkopíruje obsah paměti, proto si graf dále „žije vlastním životem“

Možnost opravy 2Zcela nezávislá možnost je implementace Jarníkova algoritmu

Děkuji za pozornost

Text této prezentace na blog.kostecky.cz

Zdrojový kód na www.kostecky.cz/archiv/mpzz-kruscal-source.zip