Apprentissage interactif de la théorie des graphes
Apprentissage interactif de la théorie des graphes
Guest User
Using app without sign in
Calculateur parallèle d'arbre couvrant minimal
Algorithme ACM parallèle, ajoute les arêtes les moins chères des composantes
Sélectionnez un algorithme et générez les étapes pour commencer la visualisation
L'algorithme de Boruvka, publié en 1926 et le plus ancien pour l'ACM, trouve un arbre couvrant minimal en laissant chaque composante choisir simultanément son arête sortante la moins chère. Toutes les arêtes choisies sont ajoutées d'un coup, fusionnant les composantes en tours parallèles.
Chaque tour balaie toutes les arêtes et enregistre, pour chaque composante, l'arête de poids minimal qui la quitte. Ces arêtes sont ajoutées à la forêt, réduisant d'au moins la moitié le nombre de composantes, si bien que seuls O(log V) tours sont nécessaires. Chaque tour coûte O(E), soit un total de O(E log V). Comme chaque tour est un simple balayage parallèle, Boruvka est la base naturelle du calcul d'ACM parallèle et distribué.
L'algorithme de Boruvka a été conçu à l'origine pour planifier un réseau électrique en Moravie et sous-tend aujourd'hui les implémentations parallèles d'ACM sur GPU et clusters, ainsi que des algorithmes hybrides mêlant tours de Boruvka et phases de Prim ou Kruskal. En entretien, il apparaît surtout comme point de discussion sur la conception d'algorithmes parallèles.
Chaque composante choisit sa propre arête sortante la moins chère, et toutes ces sélections sont appliquées d'un coup. Des tours plutôt que des étapes, et c'est précisément ce qui rend l'algorithme parallélisable.
Boruvka(graphe):
creerEnsemble(v) pour chaque sommet
acm = []
tant qu il reste plus d une composante:
moinsChere = {} // par composante
pour chaque arete (u, v, w):
a = trouver(u); b = trouver(v)
si a == b: continuer // arete interne
si w < moinsChere[a]: moinsChere[a] = (u,v,w)
si w < moinsChere[b]: moinsChere[b] = (u,v,w)
pour chaque arete e dans moinsChere.valeurs():
si trouver(e.u) != trouver(e.v): // peut-etre deja unies
unir(e.u, e.v); acm.ajouter(e)La garde de la seconde boucle est indispensable, et non une précaution superflue. Deux composantes choisissent fréquemment la même arête, une depuis chaque extrémité, et l'appliquer deux fois ajouterait un doublon. La correction exige des poids d'arêtes distincts, ou une règle de départage cohérente comme la comparaison des identifiants d'arêtes: sans une telle règle, plusieurs composantes peuvent chacune retenir une arête différente de même poids et former ensemble un cycle.
Construis l'arbre couvrant de poids minimum sur le graphe déjà utilisé pour Prim et Kruskal, afin de comparer directement les trois méthodes.
Graphe d'exemple: Arêtes non orientées A-B (2), A-C (3), B-C (1), C-D (4) et B-D (7).
L'arbre couvrant de poids minimum est A-B, B-C et C-D pour un poids total de 2 + 1 + 4 = 7, soit le même arbre que celui produit par Prim et Kruskal. Boruvka y est parvenu en un tour au lieu de trois étapes séquentielles, et c'est tout l'intérêt: chaque tour divise au moins par deux le nombre de composantes, puisque chacune fusionne avec au moins une autre, si bien que O(log V) tours suffisent toujours. Avec quatre sommets, un seul tour a ici suffi.
Temps: O(E log V) · Espace: O(V + E)
Chaque tour parcourt toutes les arêtes une fois en O(E) pour déterminer l'arête sortante la moins chère de chaque composante. Pendant un tour, chaque composante fusionne avec au moins une autre, le nombre de composantes est donc au moins divisé par deux, ce qui borne le nombre de tours par le logarithme en base 2 de V. La multiplication donne O(E log V), identique à Prim et Kruskal. La propriété distinctive est qu'au sein d'un tour chaque composante travaille indépendamment, si bien que le parcours se parallélise directement; c'est pourquoi Boruvka sous-tend les implémentations d'ACM sur GPU et en environnement distribué, alors que Prim et Kruskal, intrinsèquement séquentiels, ne s'y prêtent pas. Les algorithmes hybrides exécutent quelques tours de Boruvka pour réduire le graphe, puis basculent sur Prim.
Les trois algorithmes classiques d'ACM coûtent O(E log V). La différence est structurelle.
| Alternative | À préférer quand | Coût |
|---|---|---|
| Algorithme de Prim | Code séquentiel sur un graphe dense. Un arbre, une file de priorité, simple à implémenter. | O(E log V) ou O(V^2) |
| Algorithme de Kruskal | Graphes creux ou arêtes prétriées, et graphes non connexes où une forêt convient. | O(E log E) |
| Boruvka | Exécution parallèle ou distribuée, chaque tour étant un parcours indépendant par composante. | O(E log V) |
| Hybride Boruvka puis Prim | Très grands graphes. Quelques tours de Boruvka contractent le graphe, puis Prim termine sur le plus petit. | O(E log log V) en pratique |
Lire l'article complet: Minimum Spanning Trees: Prim, Kruskal and Boruvka
Algorithmes associés: Algorithme de Prim, Algorithme de Kruskal