Minimālais aptverošais koks (MST) jeb minimālā svara aptverošais koks svērtam, savienotam, nevirzītam grafikam ir aptverošs koks, kura svars ir mazāks vai vienāds ar katra cita aptverošā koka svaru. Lai uzzinātu vairāk par minimālo platuma koku, skatiet Šis raksts .
Ievads Kruskal algoritmā:
Šeit mēs apspriedīsim Kruskal algoritms lai atrastu dotā svērtā grafika MST.
Kruskal algoritmā kārtojiet visas dotā grafika malas augošā secībā. Pēc tam tas turpina pievienot jaunas malas un mezglus MST, ja tikko pievienotā mala neveido ciklu. Vispirms tā izvēlas minimālo svērto malu un beidzot maksimālo svērto malu. Tādējādi mēs varam teikt, ka tas katrā solī veic lokāli optimālu izvēli, lai atrastu optimālo risinājumu. Tāpēc šis ir a Tālāk ir norādītas darbības, lai atrastu MST, izmantojot Kruskal algoritmu:
- Sakārtojiet visas malas to svara secībā, kas nesamazinās.
- Izvēlieties mazāko malu. Pārbaudiet, vai tas veido ciklu ar līdz šim izveidoto aptverošo koku. Ja cikls nav izveidots, iekļaujiet šo malu. Pretējā gadījumā izmetiet to.
- Atkārtojiet 2. darbību, līdz aptverošajā kokā ir (V-1) malas.
2. darbība izmanto Union-Find algoritms ciklu noteikšanai.
Tāpēc mēs iesakām izlasīt šo ziņu kā priekšnoteikumu.
- Savienības meklēšanas algoritms | 1. iestatījums (noteikt ciklu diagrammā)
- Union-Find algoritms | 2. kopa (savienojums pēc ranga un ceļa saspiešanas)
Kruskal algoritms, lai atrastu minimālo izmaksu aptverošo koku, izmanto mantkārīgo pieeju. Mantkārīgā izvēle ir izvēlēties mazāko svara malu, kas neizraisa ciklu līdz šim konstruētajā MST. Ļaujiet mums to saprast ar piemēru:
Ilustrācija:
Tālāk ir parādīta iepriekš minētās pieejas ilustrācija:
Ievades diagramma:
Grafikā ir 9 virsotnes un 14 malas. Tātad izveidotajam minimālajam stiepšanās kokam būs (9 – 1) = 8 malas.
Pēc šķirošanas:
Svars Avots Galamērķis 1 7 6 2 8 2 2 6 5 4 0 1 4 2 5 6 8 6 7 2 3 7 7 8 8 0 7 8 1 2 9 3 4 10 5 4 vienpadsmit 1 7 14 3 5 Tagad atlasiet visas malas pa vienai no sakārtotā malu saraksta
1. darbība: Pick mala 7-6. Cikls neveidojas, iekļaujiet to.
Pievienojiet malu 7-6 MST
2. darbība: Pick mala 8-2. Cikls neveidojas, iekļaujiet to.
Pievienojiet malu 8-2 MST
3. darbība: Pick mala 6-5. Cikls neveidojas, iekļaujiet to.
Pievienojiet MST malu 6-5
notīrīt kešatmiņu npm4. darbība: Izvēlēties malu 0-1. Cikls neveidojas, iekļaujiet to.
Pievienojiet malu 0-1 MST
5. darbība: Izvēlieties malu 2-5. Cikls neveidojas, iekļaujiet to.
Pievienojiet malu 2-5 MST
6. darbība: Pick mala 8-6. Tā kā šīs malas iekļaušana izraisa ciklu, izmetiet to. Izvēlieties malu 2-3: Cikls neveidojas, iekļaujiet to.
Pievienojiet 2-3 malu MST
7. darbība: Pick mala 7-8. Tā kā šīs malas iekļaušana izraisa ciklu, izmetiet to. Izvēles mala 0-7. Cikls neveidojas, iekļaujiet to.
Pievienojiet malu 0-7 MST
8. darbība: Izvēlieties malu 1-2. Tā kā šīs malas iekļaušana izraisa ciklu, izmetiet to. Izvēlieties malu 3-4. Cikls neveidojas, iekļaujiet to.
Pievienojiet MST malu 3-4
Piezīme: Tā kā MST iekļauto šķautņu skaits ir vienāds ar (V – 1), algoritms šeit apstājas
Tālāk ir aprakstīta iepriekš minētās pieejas īstenošana.
C++
// C++ program for the above approach> > #include> using> namespace> std;> > // DSU data structure> // path compression + rank by union> class> DSU {> >int>* parent;> >int>* rank;> > public>:> >DSU(>int> n)> >{> >parent =>new> int>[n];> >rank =>new> int>[n];> > >for> (>int> i = 0; i parent[i] = -1; rank[i] = 1; } } // Find function int find(int i) { if (parent[i] == -1) return i; return parent[i] = find(parent[i]); } // Union function void unite(int x, int y) { int s1 = find(x); int s2 = find(y); if (s1 != s2) { if (rank[s1] parent[s1] = s2; } else if (rank[s1]>rangs[s2]) { vecāks[s2] = s1; } else { vecāks[s2] = s1; rangs[s1] += 1; } } } }; class Graph { vectorint>> edgelist; int V; public: Graph(int V) { this->V = V; } // Funkcija malas pievienošanai grafikam void addEdge(int x, int y, int w) { edgelist.push_back({ w, x, y }); } void kruskals_mst() { // Kārtot visas malas sort(edgelist.begin(), edgelist.end()); // Inicializēt DSU DSU s(V); int ans = 0; cout<< 'Following are the edges in the ' 'constructed MST' << endl; for (auto edge : edgelist) { int w = edge[0]; int x = edge[1]; int y = edge[2]; // Take this edge in MST if it does // not forms a cycle if (s.find(x) != s.find(y)) { s.unite(x, y); ans += w; cout << x << ' -- ' << y << ' == ' << w << endl; } } cout << 'Minimum Cost Spanning Tree: ' << ans; } }; // Driver code int main() { Graph g(4); g.addEdge(0, 1, 10); g.addEdge(1, 3, 15); g.addEdge(2, 3, 4); g.addEdge(2, 0, 6); g.addEdge(0, 3, 5); // Function call g.kruskals_mst(); return 0; }> |
>
>
C
// C code to implement Kruskal's algorithm> > #include> #include> > // Comparator function to use in sorting> int> comparator(>const> void>* p1,>const> void>* p2)> {> >const> int>(*x)[3] = p1;> >const> int>(*y)[3] = p2;> > >return> (*x)[2] - (*y)[2];> }> > // Initialization of parent[] and rank[] arrays> void> makeSet(>int> parent[],>int> rank[],>int> n)> {> >for> (>int> i = 0; i parent[i] = i; rank[i] = 0; } } // Function to find the parent of a node int findParent(int parent[], int component) { if (parent[component] == component) return component; return parent[component] = findParent(parent, parent[component]); } // Function to unite two sets void unionSet(int u, int v, int parent[], int rank[], int n) { // Finding the parents u = findParent(parent, u); v = findParent(parent, v); if (rank[u] parent[u] = v; } else if (rank[u]>rangs[v]) { vecāks[v] = u; } else { vecāks[v] = u; // Tā kā rangs palielinās, ja // divu kopu rindas ir vienādas rangs[u]++; } } // MST tukšuma atrašanas funkcija kruskalAlgo(int n, int edge[n][3]) { // Vispirms sakārtojam malu masīvu augošā secībā // lai varētu piekļūt minimālajiem attālumiem/izmaksām qsort(edge , n, izmērs(mala[0]), salīdzinājums); iekšējais vecāks[n]; int rank[n]; // Funkcija, lai inicializētu vecāku[] un rangu[] makeSet(parent, rangs, n); // Lai saglabātu minimālās izmaksas int minCost = 0; printf( 'Tālāk ir redzamas malas konstruētajā MST
'); for (int i = 0; i int v1 = atrastVecāks(vecāks, mala[i][0]); int v2 = atrastVecāks(vecāks, mala[i][1]); int wt = mala[i][2] // Ja vecāki ir atšķirīgi, tas // nozīmē, ka tie ir apvienoti if (v1 != v2) { unionSet(v1, v2, parent, rank, n); '%d -- %d == %d
', edge[i][0], edge[i][1], wt } } printf('Minimālās izmaksas aptverošais koks: %d); n', minCost); , { 1, 3, 15 }, { 2, 3, 4 } }; |
>
// Java program for Kruskal's algorithm>>import>java.util.ArrayList;>import>java.util.Comparator;>import>java.util.List;>>public>class>KruskalsMST {>>>// Defines edge structure>>static>class>Edge {>>int>src, dest, weight;>>>public>Edge(>int>src,>int>dest,>int>weight)>>{>>this>.src = src;>>this>.dest = dest;>>this>.weight = weight;>>}>>}>>>// Defines subset element structure>>static>class>Subset {>>int>parent, rank;>>>public>Subset(>int>parent,>int>rank)>>{>>this>.parent = parent;>>this>.rank = rank;>>}>>}>>>// Starting point of program execution>>public>static>void>main(String[] args)>>{>>int>V =>4>;>>List graphEdges =>new>ArrayList(>>List.of(>new>Edge(>0>,>1>,>10>),>new>Edge(>0>,>2>,>6>),>>new>Edge(>0>,>3>,>5>),>new>Edge(>1>,>3>,>15>),>>new>Edge(>2>,>3>,>4>)));>>>// Sort the edges in non-decreasing order>>// (increasing with repetition allowed)>>graphEdges.sort(>new>Comparator() {>>@Override>public>int>compare(Edge o1, Edge o2)>>{>>return>o1.weight - o2.weight;>>}>>});>>>kruskals(V, graphEdges);>>}>>>// Function to find the MST>>private>static>void>kruskals(>int>V, List edges)>>{>>int>j =>0>;>>int>noOfEdges =>0>;>>>// Allocate memory for creating V subsets>>Subset subsets[] =>new>Subset[V];>>>// Allocate memory for results>>Edge results[] =>new>Edge[V];>>>// Create V subsets with single elements>>for>(>int>i =>0>; i subsets[i] = new Subset(i, 0); } // Number of edges to be taken is equal to V-1 while (noOfEdges 1) { // Pick the smallest edge. And increment // the index for next iteration Edge nextEdge = edges.get(j); int x = findRoot(subsets, nextEdge.src); int y = findRoot(subsets, nextEdge.dest); // If including this edge doesn't cause cycle, // include it in result and increment the index // of result for next edge if (x != y) { results[noOfEdges] = nextEdge; union(subsets, x, y); noOfEdges++; } j++; } // Print the contents of result[] to display the // built MST System.out.println( 'Following are the edges of the constructed MST:'); int minCost = 0; for (int i = 0; i System.out.println(results[i].src + ' -- ' + results[i].dest + ' == ' + results[i].weight); minCost += results[i].weight; } System.out.println('Total cost of MST: ' + minCost); } // Function to unite two disjoint sets private static void union(Subset[] subsets, int x, int y) { int rootX = findRoot(subsets, x); int rootY = findRoot(subsets, y); if (subsets[rootY].rank subsets[rootY].parent = rootX; } else if (subsets[rootX].rank subsets[rootX].parent = rootY; } else { subsets[rootY].parent = rootX; subsets[rootX].rank++; } } // Function to find parent of a set private static int findRoot(Subset[] subsets, int i) { if (subsets[i].parent == i) return subsets[i].parent; subsets[i].parent = findRoot(subsets, subsets[i].parent); return subsets[i].parent; } } // This code is contributed by Salvino D'sa>>>Python3
# Python program for Kruskal's algorithm to find># Minimum Spanning Tree of a given connected,># undirected and weighted graph>>># Class to represent a graph>class>Graph:>>>def>__init__(>self>, vertices):>>self>.V>=>vertices>>self>.graph>=>[]>>># Function to add an edge to graph>>def>addEdge(>self>, u, v, w):>>self>.graph.append([u, v, w])>>># A utility function to find set of an element i>># (truly uses path compression technique)>>def>find(>self>, parent, i):>>if>parent[i] !>=>i:>>># Reassignment of node's parent>># to root node as>># path compression requires>>parent[i]>=>self>.find(parent, parent[i])>>return>parent[i]>>># A function that does union of two sets of x and y>># (uses union by rank)>>def>union(>self>, parent, rank, x, y):>>># Attach smaller rank tree under root of>># high rank tree (Union by Rank)>>if>rank[x] parent[x] = y elif rank[x]>rangs[y]: vecāks[y] = x # Ja rangi ir vienādi, izveidojiet vienu kā saknes # un palieliniet tā rangu par vienu citu: vecāks[y] = x rangs[x] += 1 # Galvenā konstruēšanas funkcija MST # izmantojot Kruskal algoritmu def KruskalMST(self): # Tas saglabās iegūto MST rezultātu = [] # Indeksa mainīgais, ko izmanto sakārtotām malām i = 0 # Indeksa mainīgais, ko izmanto rezultātam[] e = 0 # Kārtot visas malas # to svara nesamazināšanās secībā self.graph = sakārtots(self.graph, key=lambda item: item[2]) vecāks = [] rangs = [] # Izveidojiet V apakškopas ar atsevišķiem elementiem mezglam diapazonā(self.V): parent.append(node) rank.append(0) # Ņemamo malu skaits ir mazāks par V-1, kamēr e>>C#
java pārtraukumam
// C# Code for the above approach>>using>System;>>class>Graph {>>>// A class to represent a graph edge>>class>Edge : IComparable {>>public>int>src, dest, weight;>>>// Comparator function used for sorting edges>>// based on their weight>>public>int>CompareTo(Edge compareEdge)>>{>>return>this>.weight - compareEdge.weight;>>}>>}>>>// A class to represent>>// a subset for union-find>>public>class>subset {>>public>int>parent, rank;>>};>>>// V->Nē. virsotņu & E->malu skaits>>int> V, E;>>>// Collection of all edges>>Edge[] edge;>>>// Creates a graph with V vertices and E edges>>Graph(>int>v,>int>e)>>{>>V = v;>>E = e;>>edge =>new>Edge[E];>>for>(>int>i = 0; i edge[i] = new Edge(); } // A utility function to find set of an element i // (uses path compression technique) int find(subset[] subsets, int i) { // Find root and make root as // parent of i (path compression) if (subsets[i].parent != i) subsets[i].parent = find(subsets, subsets[i].parent); return subsets[i].parent; } // A function that does union of // two sets of x and y (uses union by rank) void Union(subset[] subsets, int x, int y) { int xroot = find(subsets, x); int yroot = find(subsets, y); // Attach smaller rank tree under root of // high rank tree (Union by Rank) if (subsets[xroot].rank subsets[xroot].parent = yroot; else if (subsets[xroot].rank>subsets[yroot].rank) subsets[yroot].parent = xroot; // Ja rangi ir vienādi, izveidojiet vienu kā sakni // un palieliniet tā rangu par vienu citu { subsets[yroot].parent = xroot; apakškopas[xroot].rank++; } } // Galvenā funkcija MST konstruēšanai // izmantojot Kruskal's algoritmu void KruskalMST() { // Tas saglabās // iegūto MST Edge[] rezultāts = new Edge[V]; // Indeksa mainīgais, ko izmanto rezultātam[] int e = 0; // Indeksa mainīgais, ko izmanto sakārtotām malām int i = 0; for (i = 0; i rezultāts[i] = new Edge(); // Sakārtot visas malas nesamazināmā // secībā pēc to svara. Ja mums nav atļauts // mainīt doto grafiku, varam izveidot // malu masīva kopija Array.Sort(edge) // Piešķirt atmiņu V apakškopu izveidošanai subset[] subsets = new subset[V] for (i = 0; i subsets[i] = new subset() // Izveidot V apakškopas ar atsevišķiem elementiem priekš (int v = 0; v apakškopas[v].parent = v; apakškopas[v].rank = 0; } i = 0; // ņemamo malu skaits ir vienāds uz V-1 while (e // Izvēlieties mazāko malu. Un palieliniet // indeksu nākamajai iterācijai Edge next_edge = new Edge(); next_edge = edge[i++]; int x = find(subsets, next_edge.src); int y = find(subsets, next_edge.dest) // Ja šīs malas iekļaušana neizraisa ciklu, // iekļaujiet to rezultātā un palieliniet // rezultāta indeksu nākamajai malai if (x != y) { rezultāts[e++] = next_edge; uzbūvētais MST'); int minimumsIzmaksas = 0; for (i = 0; i Console.WriteLine(rezultāts[i].src + ' -- ' + rezultāts[i].dest. + ' == ' + rezultāts[i].svars); minimālā maksa += rezultāts[i].weight } Console.WriteLine('Minimum Cost Spanning Tree: ' + minimumCost Console.ReadLine(} // Draivera kods public static void Main(String[] args)); int V = 4 int E = 5; graph.edge[0].weight = 10; // pievienot malu 0-2 graph.edge[1].dest = 2; ; // pievienot malu 0-3 graph.edge[2].dest = 3; edge[3].src = 1 graph.edge[3].weight = 15 // pievienot malu 2-3 graph.edge[4].src = 2; .edge[4].dest = 3;>
>// JavaScript implementation of the krushkal's algorithm.>>function>makeSet(parent,rank,n)>{>>for>








