Un arbre couvrant minimum (MST) ou arbre couvrant de poids minimum pour un graphique pondéré, connecté et non orienté est un arbre couvrant avec un poids inférieur ou égal au poids de tous les autres arbres couvrant. Pour en savoir plus sur l'arbre couvrant minimum, reportez-vous à Cet article .
Introduction à l'algorithme de Kruskal :
Nous discuterons ici L'algorithme de Kruskal pour trouver le MST d’un graphique pondéré donné.
Dans l'algorithme de Kruskal, triez toutes les arêtes du graphique donné par ordre croissant. Ensuite, il continue d'ajouter de nouvelles arêtes et nœuds dans le MST si l'arête nouvellement ajoutée ne forme pas un cycle. Il sélectionne d'abord le bord pondéré minimum et enfin le bord pondéré maximum. On peut donc dire qu'il fait un choix localement optimal à chaque étape afin de trouver la solution optimale. Il s'agit donc d'un Vous trouverez ci-dessous les étapes pour trouver MST à l’aide de l’algorithme de Kruskal :
- Triez toutes les arêtes par ordre non décroissant de leur poids.
- Choisissez le plus petit bord. Vérifiez s'il forme un cycle avec l'arbre couvrant formé jusqu'à présent. Si le cycle n'est pas formé, incluez cette arête. Sinon, jetez-le.
- Répétez l'étape 2 jusqu'à ce qu'il y ait (V-1) arêtes dans l'arbre couvrant.
Étape 2 utilise le Algorithme Union-Find pour détecter les cycles.
Nous vous recommandons donc de lire le post suivant comme prérequis.
- Algorithme de recherche d'union | Ensemble 1 (Détecter le cycle dans un graphique)
- Algorithme de recherche d'union | Ensemble 2 (Union par rang et compression de chemin)
L'algorithme de Kruskal pour trouver l'arbre couvrant le coût minimum utilise l'approche gloutonne. Le choix gourmand consiste à choisir le plus petit bord de poids qui ne provoque pas de cycle dans le MST construit jusqu'à présent. Comprenons-le avec un exemple :
recherche binaire
Illustration:
Vous trouverez ci-dessous l’illustration de l’approche ci-dessus :
Graphique d'entrée :
Le graphe contient 9 sommets et 14 arêtes. Ainsi, l'arbre couvrant minimum formé aura (9 – 1) = 8 arêtes.
Après tri :
Poids Source Destination 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 dix 5 4 onze 1 7 14 3 5 Maintenant, sélectionnez toutes les arêtes une par une dans la liste triée des arêtes.
Étape 1: Choisissez le bord 7-6. Aucun cycle ne se forme, incluez-le.
Ajouter le bord 7-6 dans le MST
Étape 2: Choisissez le bord 8-2. Aucun cycle ne se forme, incluez-le.
Ajouter le bord 8-2 dans le MST
Étape 3: Choisissez le bord 6-5. Aucun cycle ne se forme, incluez-le.
Ajoutez le bord 6-5 dans le MST
Étape 4: Choisissez le bord 0-1. Aucun cycle ne se forme, incluez-le.
Ajouter le bord 0-1 dans le MST
Étape 5 : Choisissez le bord 2-5. Aucun cycle ne se forme, incluez-le.
Ajouter les bords 2 à 5 dans le MST
Étape 6 : Choisissez le bord 8-6. Puisque l’inclusion de cette arête entraîne le cycle, supprimez-la. Choisissez le bord 2-3 : Aucun cycle ne se forme, incluez-le.
Ajouter le bord 2-3 dans le MST
Étape 7 : Choisissez le bord 7-8. Puisque l’inclusion de cette arête entraîne le cycle, supprimez-la. Choisissez le bord 0-7. Aucun cycle ne se forme, incluez-le.
Ajouter le bord 0-7 dans MST
Étape 8 : Choisissez le bord 1-2. Puisque l’inclusion de cette arête entraîne le cycle, supprimez-la. Choisissez le bord 3-4. Aucun cycle ne se forme, incluez-le.
Ajouter le bord 3-4 dans le MST
Note: Puisque le nombre d'arêtes incluses dans le MST est égal à (V – 1), l'algorithme s'arrête ici
Vous trouverez ci-dessous la mise en œuvre de l’approche ci-dessus :
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]>rang[s2]) { parent[s2] = s1; } autre { parent[s2] = s1; rang[s1] += 1 ; } } } } ; classe Graphique { vectorint>> liste de bords ; à la TV; public : Graphique (int V) { this->V = V ; } // Fonction pour ajouter une arête dans un graphique void addEdge(int x, int y, int w) { edgelist.push_back({ w, x, y }); } void kruskals_mst() { // Trie tous les bords sort(edgelist.begin(), edgelist.end()); // Initialise le DSU DSU s(V); entier 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]>rang[v]) { parent[v] = u; } autre { parent[v] = u; // Puisque le rang augmente si // les rangs de deux ensembles sont identiques Rank[u]++; } } // Fonction pour trouver le MST void kruskalAlgo(int n, int edge[n][3]) { // Nous trions d'abord le tableau de bords par ordre croissant // afin de pouvoir accéder aux distances/coût minimum qsort(edge , n, sizeof(edge[0]), comparateur); int parent[n] ; rang int[n] ; // Fonction pour initialiser parent[] et Rank[] makeSet(parent, Rank, n); // Pour stocker le coût minimum int minCost = 0; printf( 'Voici les bords du MST construit
'); pour (int i = 0; i int v1 = findParent(parent, edge[i][0]); int v2 = findParent(parent, edge[i][1]); int wt = edge[i][2] ; // Si les parents sont différents, cela // signifie qu'ils sont dans des ensembles différents, donc // les unit if (v1 != v2) { unionSet(v1, v2, parent, Rank, n); '%d -- %d == %d
', edge[i][0], edge[i][1], wt); } } printf('Arbre couvrant le coût minimum : %d n', minCost); } // Code du pilote int main() { int edge[5][3] = { { 0, 1, 10 }, { 0, 2, 6 }, { 0, 3, 5 } , { 1, 3, 15 }, { 2, 3, 4 } }; kruskalAlgo(5, bord); |
>top 10 hentaï
// 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]>rang[y] : parent[y] = x # Si les rangs sont identiques, alors créez-en un comme racine # et incrémentez son rang d'un autre : parent[y] = x rang[x] += 1 # La fonction principale à construire MST # en utilisant l'algorithme de Kruskal def KruskalMST(self): # Ceci stockera le résultat MST résultant = [] # Une variable d'index, utilisée pour les arêtes triées i = 0 # Une variable d'index, utilisée pour le résultat[] e = 0 # Trier toutes les arêtes dans # l'ordre non décroissant de leur # poids self.graph = sorted(self.graph, key=lambda item: item[2]) parent = [] Rank = [] # Créer des sous-ensembles en V avec des éléments uniques pour le nœud dans la plage (self.V) : parent.append (node) Rank.append (0) # Le nombre d'arêtes à prendre est inférieur à V-1 tandis que e>>C#
ymail
// 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->Non. de sommets & E->nombre d'arêtes>>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>sous-ensembles[yroot].rank) sous-ensembles[yroot].parent = xroot; // Si les rangs sont identiques, créez-en un en tant que racine // et incrémentez son rang d'un autre { subsets[yroot].parent = xroot; sous-ensembles[xroot].rank++; } } // La fonction principale pour construire MST // en utilisant l'algorithme de Kruskal void KruskalMST() { // Ceci stockera le // MST Edge[] résultant result = new Edge[V]; // Une variable d'index, utilisée pour result[] int e = 0; // Une variable d'index, utilisée pour les arêtes triées int i = 0; for (i = 0; i result[i] = new Edge(); // Trie toutes les arêtes dans // l'ordre non décroissant de leur poids. Si nous ne sommes pas autorisés // à modifier le graphique donné, nous pouvons créer // une copie du tableau d'arêtes Array.Sort(edge); // Allouer de la mémoire pour créer des sous-ensembles V subset[] subsets = new subset[V]; ; // Crée des sous-ensembles V avec des éléments uniques pour (int v = 0; v subsets[v].parent = v; subsets[v].rank = 0; } i = 0; // Le nombre d'arêtes à prendre est égal à V-1 while (e // Choisissez le plus petit bord. Et incrémentez // l'index pour la prochaine itération Edge next_edge = new Edge(); next_edge = edge[i++]; int x = find(subsets, next_edge.src); int y = find(subsets, next_edge.dest); // Si l'inclusion de cette arête ne provoque pas de cycle, // incluez-la dans le résultat et incrémentez l'index // du résultat pour l'arête suivante if (x != y) { result[e++] = next_edge; Union(subsets, x, y); } } // Imprime le contenu de result[] pour afficher // la console MST construite.WriteLine('Voici les bords dans ' + ' le MST construit'); int coût minimum = 0 ; pour (i = 0; i Console.WriteLine(result[i].src + ' -- ' + result[i].dest + ' == ' + result[i].weight); minimumCost += result[i].weight; } Console.WriteLine('Arbre couvrant le coût minimum : ' + minimumCost(); } // Code du pilote public static void Main(String[] args) { int V = 4; int E = 5; Graph graph = new Graph(V, E); // ajoute le bord 0-1 graph.edge[0].src = 0; graph.edge[0].weight = 10; // ajouter le bord 0-2 graph.edge[1].src = 0; graph.edge[1].dest = 2; ; // ajoute le bord 0-3 graph.edge[2].src = 0; graph.edge[2].dest = 3; graph.edge[2].weight = 5; edge[3].src = 1; graph.edge[3].dest = 3; graph.edge[3].weight = 15; // ajouter le bord 2-3 graph.edge[4].src = 2; .edge[4].dest = 3; graph.edge[4].weight = 4; // Appel de fonction graph.KruskalMST(); } } // Ce code est fourni par Aakash Hasija>>>Javascript
>// JavaScript implementation of the krushkal's algorithm.>>function>makeSet(parent,rank,n)>{>>for>(let i=0;i { parent[i]=i; rank[i]=0; } } function findParent(parent,component) { if(parent[component]==component) return component; return parent[component] = findParent(parent,parent[component]); } function unionSet(u, v, parent, rank,n) { //this function unions two set on the basis of rank //as shown below u=findParent(parent,u); v=findParent(parent,v); if(rank[u] { parent[u]=v; } else if(rank[u] { parent[v]=u; } else { parent[v]=u; rank[u]++;//since the rank increases if the ranks of two sets are same } } function kruskalAlgo(n, edge) { //First we sort the edge array in ascending order //so that we can access minimum distances/cost edge.sort((a, b)=>{ retourner a[2] - b[2]; }) //La fonction de tri rapide intégrée est fournie avec stdlib.h //allez sur https://www.techcodeview.com Le tri des bords prend un temps O(E * logE). Après le tri, nous parcourons toutes les arêtes et appliquons l'algorithme de recherche d'union. Les opérations de recherche et d'union peuvent prendre au plus un temps O(logV). La complexité globale est donc le temps O(E * logE + E * logV). La valeur de E peut être au plus O(V2), donc O(logV) et O(logE) sont identiques. Par conséquent, la complexité temporelle globale est O(E * logE) ou O(E*logV) Espace auxiliaire : O(V + E), où V est le nombre de sommets et E est le nombre d'arêtes dans le graphique. Cet article est compilé par Aashish Barnwal et révisé par l'équipe techcodeview.com.>








