Kruskalův algoritmus
Kruskalův algoritmus

Kruskalův algoritmus slouží k nalezení minimální kostry grafu (kostry takové, že součet vah jejích hran je minimální). Algoritmus byl poprvé publikován v roce 1956 Josephem Kruskalem.

Princip

Kruskalův algoritmus nejprve setřídí hrany dle jejich váhy (od nejmenší) a následně přidává hrany do grafu takovým způsobem, aby nevznikl žádný cyklus (tj. procedura terminuje po přidání \\vert U \\vert -1 hran).

K zajištění acykličnosti si algoritmus pomocí datové struktury disjoint set udržuje pro každý uzel informaci o příslušnosti ke komponentě souvislosti. Disjoint set poskytuje dvě operace: union (spojí dvě komponenty souvislosti) a find (zjistí pro daný uzel příslušnost ke komponentě souvislosti).

Asymptotická složitost algoritmu

Časová složitost algoritmu je v případě použití řadicího algoritmu založeného na porovnávání O(\\vert H\\vert \\cdot \\log \\vert H \\vert). Pokud jsou hrany již předřazeny, nebo je možno k jejich seřazení použít řadicí algoritmus s lineární složitostí (např. counting sort), tak je složitost Kruskalova algoritmu rovna O(\\vert H\\vert \\cdot \\alpha(\\vert H \\vert)), kde \\alpha je inverzní Ackermannova funkce (odpovídá složitosti operací union a find).


Kód

01./**
02. * Kruskaluv algoritmus
03. * @param graph graf
04. * @param w vahy jednotlivych hran
05. * @return minimalni kostra grafu
06. */
07.SpanningTree kruskalAlgorithm(Graph graph, weights w)
08.    SpanningTree tree //kostra
09.    for Node n : graph do
10.        makeSet(n) //kazdy uzel je v samostatnem setu
11.    List edges = sort(graph.getEdges(), w) //seradi hrany podle vah
12.     
13.    for Edge e in edges do
14.        if findSet(e.start) != findSet(e.end) //pokud jsou pocatecni a koncovy uzel v ruznych setech (netvorime cyklus)
15.            tree.add(e) //pridej hranu do kostry
16.            union(e.start, e.end) //sety spojime v jeden
17.            if tree.edgeCount() == graph.nodeCount() - 1 //pokud uz je kostra cela
18.                break //konec pridavani hran
19.    return tree
001./**
002. * Kruskaluv algoritmus
003. * @author Pavel Micka
004. */
005.public class KruskalAlgorithm {
006.    /**
007.     * Nalezne minimalni kostru neorientovaneho grafu o n uzlech (cisla uzlu
008.     * 0, 1, ..., n-1)
009.     * @param edges hrany neorientovaneho grafu
010.     * @param nodeCount pocet uzlu neorientovaneho grafu (n)
011.     * @return minimalni kostra
012.     */
013.    public static List<Edge> kruskalAlgorithm(List<Edge> edges, int nodeCount) {
014.        DisjointSet ds = new DisjointSet(nodeCount);
015.        List<Edge> spanningTree = new ArrayList<Edge>();
016.        Collections.sort(edges);
017.        int i = 0;
018.        while (i != edges.size() && spanningTree.size() != nodeCount - 1) {
019.            Edge e = edges.get(i);
020.            if(ds.find(e.getFrom()) != ds.find(e.getTo())){
021.                spanningTree.add(e);
022.                ds.union(e.getFrom(), e.getTo());
023.            }
024.            i++;
025.        }
026.        return spanningTree;
027.    }
028.}
029. 
030. 
031.// ***************************** //
032.// *     DATOVE STRUKTURY      * //
033.// ***************************** //
034. 
035. 
036./**
037. * Hrana neorientovaneho grafu
038. * @author Pavel Micka
039. */
040.class Edge implements Comparable<Edge> {
041.    private int from; //uzel z
042.    private int to; //uzel do
043.    private int weight; //vaha
044.    public Edge(int from, int to, int weight) {
045.        this.from = from;
046.        this.to = to;
047.        this.weight = weight;
048.    }
049.    /**
050.     * Provede porovnani hran dle vahy (vyssi vaha == vetsi)
051.     * @param o
052.     * @return
053.     */
054.    public int compareTo(Edge o) {
055.        if (this.getWeight() > o.getWeight()) {
056.            return 1;
057.        } else if (this.getWeight() < o.getWeight()) {
058.            return -1;
059.        } else {
060.            return 0;
061.        }
062.    }
063. 
064.    /**
065.     * @return the from
066.     */
067.    public int getFrom() {
068.        return from;
069.    }
070. 
071.    /**
072.     * @param from the from to set
073.     */
074.    public void setFrom(int from) {
075.        this.from = from;
076.    }
077. 
078.    /**
079.     * @return the to
080.     */
081.    public int getTo() {
082.        return to;
083.    }
084. 
085.    /**
086.     * @param to the to to set
087.     */
088.    public void setTo(int to) {
089.        this.to = to;
090.    }
091. 
092.    /**
093.     * @return the weight
094.     */
095.    public int getWeight() {
096.        return weight;
097.    }
098. 
099.    /**
100.     * @param weight the weight to set
101.     */
102.    public void setWeight(int weight) {
103.        this.weight = weight;
104.    }
105.}
106./**
107. * Jednoducha implementace Union-Find problemu
108. * @author Pavel Micka
109. */
110.class DisjointSet {
111. 
112.    private Node[] nodes;
113. 
114.    public DisjointSet(int nodeCount) {
115.        nodes = new Node[nodeCount];
116.        for (int i = 0; i < nodeCount; i++) {
117.            nodes[i] = new Node();
118.            nodes[i].id = i;
119.        }
120.    }
121. 
122.    /**
123.     * Provede sjednoceni komponent, ve kterych jsou uzly "a" a "b"
124.     * Union provadi vzdy do A
125.     * @param a cislo uzlu a
126.     * @param b cislo uzlu b
127.     * @return cislo reprezentanta sjednocene komponenty
128.     */
129.    public int union(int a, int b) {
130.        Node repA = nodes[find(a)];
131.        Node repB = nodes[find(b)];
132. 
133.        repB.parent = repA;
134.        return repA.id;
135.    }
136. 
137.    /**
138.     * Vrati reprezentanta zadaneho uzlu
139.     * @param a cislo uzlu, jehoz reprezentanta hledame
140.     * @return cislo reprezentanta uzlu
141.     */
142.    public int find(int a) {
143.        Node n = nodes[a];
144.        int jumps = 0;
145.        while (n.parent != null) {
146.            n = n.parent;
147.            jumps++;
148.        }
149.        if (jumps > 1) repair(a, n.id);
150.        return n.id;
151.    }
152. 
153.    /**
154.     * Provede opravu (compression) cesty
155.     * @param a
156.     * @param rootId
157.     */
158.    private void repair(int a, int rootId) {
159.        Node curr = nodes[a];
160.        while (curr.id != rootId) {
161.            Node tmp = curr.parent;
162.            curr.parent = nodes[rootId];
163.            curr = tmp;
164.        }
165.    }
166. 
167.    @Override
168.    public String toString() {
169.        StringBuilder builder = new StringBuilder();
170.        for (int i = 0; i < nodes.length; i++) {
171.            builder.append(find(i) + " ");
172.        }
173.        return builder.toString();
174.    }
175. 
176.    /**
177.     * Uzel n-arniho stromu
178.     */
179.    private static class Node {
180.        /**
181.         * Rodic
182.         */
183.        Node parent;
184.        /**
185.         * Identifikator uzlu
186.         */
187.        int id;
188.    }
189.}

Literatura

  • KOLÁŘ, Josef. Teoretická informatika. 2. vyd. Praha : Česká informatická společnost, 2004. 205 s. ISBN 80-900853-8-5.

SEO od společnosti Digital Pylon


Online casino s algoritmem

České casino online online slot-vegas.cz

Hrajte nejlepší hry jako je GoodGame Empire.





Zajímavé články: Jak najít práci snů? Zvolte kariéru v IT!, Češi mají rádi hrací automaty online, Jak funguje algoritmické obchodování Casino, Online výuka Algoritmus a online marketing mají svá pravidla, Automaty, Matematický vliv, Ratings, Jak fungují algoritmy hazardních her online: více znalostí, více peněz, SYPWAI - nástroj pro vědecký vývoj, Vynikají na globálním trhu: Nejlepší vývojáři softwaru pro online výherní automaty, Jak si vybrat nejlepší české online casino, Proč byste měli hrát online casino VPN revoluce, Kde najdeme algoritmy v každodenním životě?, Čeká vás pracovní pohovor mimo město? Podívejte se, jak dokonale zvládnout včasný příchod, 5 úžasných technologií ze světa hazardních her, Mirror and access to Mostbet, Svou kancelář můžete mít stále po ruce, Jaké výhody má digitalizovaná firma oproti off-line konkurenci?, Jaký systém vybrat pro snadné řízení výroby?, Nahradí umělá inteligence ajťáky?, Důvody, proč používat SnapTik ke stahování videí TikTok, Dokonalý den na pláži: Co si vzít s sebou, aby byl výlet zábavný a bezpečný?, Jak přežít dlouhý let?, Go pay GoodGame Empire, Blockchain, Rozhovor, Umělá inteligence, Ochranná známka pre softvér: Prečo ju registrovať?, Role kryptografických algoritmů v zabezpečení online kasin, Jaké jsou náklady na nákup 3D tiskárny?, Jak algoritmy vylepšují online zážitky v roce 2025,


Doporučujeme

Internet pro vaši firmu na míru

https://www.algoritmy.net