Upload
ivo-kostecky
View
1.065
Download
3
Embed Size (px)
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