Apprentissage interactif de la théorie des graphes
Apprentissage interactif de la théorie des graphes
Guest User
Using app without sign in
Calculateur d'arbre couvrant minimal
Construit l'ACM en croissant depuis un sommet de départ
Sélectionnez un algorithme et générez les étapes pour commencer la visualisation
L'algorithme de Prim construit un arbre couvrant de poids minimal (ACM) d'un graphe pondéré non orienté, le sous-ensemble d'arêtes reliant chaque sommet avec le plus petit poids total possible. Il fait croître un unique arbre depuis un sommet de départ arbitraire, en ajoutant toujours l'arête la moins chère atteignant un nouveau sommet.
L'algorithme conserve une file de priorité des arêtes qui traversent de l'arbre vers le reste du graphe. À chaque étape, il extrait l'arête traversante de poids minimal, ajoute son nouveau sommet à l'arbre et insère les arêtes de ce sommet dans la file. La propriété de coupe des ACM garantit que chaque arête choisie appartient à un arbre couvrant minimal. Avec un tas binaire, le temps est O(E log V).
L'algorithme de Prim conçoit des réseaux à faible coût : réseaux électriques, déploiements de fibre et de télécoms, canalisations d'eau et câblage de puces. Il sert aussi au clustering et à la segmentation d'images. Les entretiens l'associent souvent à l'algorithme de Kruskal pour évaluer la compréhension des arguments de correction glouton.
Prim fait croître un seul arbre depuis un départ arbitraire. À chaque étape il prend l'arête la moins chère ayant exactement une extrémité déjà dans l'arbre, ce qui suffit à garantir l'optimalité sans jamais revenir en arrière.
Prim(graphe, depart):
dansArbre = {depart}
fp = file de priorite des aretes sortant de depart
acm = []
tant que dansArbre ne contient pas tous les sommets:
(u, v, w) = fp.extraireMin()
si v dans dansArbre: continuer // arete perimee
acm.ajouter((u, v, w))
dansArbre.ajouter(v)
pour chaque arete (v, x, w2):
si x hors de dansArbre: fp.inserer((v, x, w2))La correction repose sur la propriété de coupe: pour toute partition des sommets en deux côtés, l'arête la moins chère traversant cette coupe appartient à un arbre couvrant de poids minimum. Prim l'applique avec la coupe « déjà dans l'arbre » contre « pas encore », et c'est pourquoi prendre l'arête traversante la moins chère est toujours sûr. Cette propriété explique aussi pourquoi aucun retour en arrière n'est nécessaire: une arête acceptée ne peut jamais devenir un mauvais choix à la lumière d'informations ultérieures, contrairement à ce qui arrive dans un problème comme le TSP.
Fais croître un arbre couvrant de poids minimum depuis A sur un petit graphe pondéré où le choix glouton rejette délibérément une arête directe en apparence moins chère.
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. Remarque qu'il compte exactement trois arêtes, une de moins que les quatre sommets, comme tout arbre couvrant. Remarque aussi qu'ici l'arbre est un chemin, ce qui rappelle qu'un arbre couvrant de poids minimum n'est pas un arbre de plus courts chemins: la distance de A à D dans l'arbre vaut 7, alors que le plus court chemin A vers C vers D dans le graphe vaut 3 + 4 = 7 et A vers B vers D vaut 9. Les deux problèmes optimisent des quantités différentes, et confondre les deux est l'erreur conceptuelle la plus fréquente sur ce sujet.
Temps: O(E log V) · Espace: O(V + E)
Avec un tas binaire, chaque arête peut être insérée une fois et extraite une fois en O(log E), et comme E vaut au plus V au carré, log E reste à un facteur constant de log V, d'où O(E log V). Chaque sommet est ajouté à l'arbre exactement une fois, ce qui borne le nombre d'itérations de la boucle externe à V. Un tas de Fibonacci avec diminution de clé au lieu d'insertion paresseuse améliore la borne en O(E + V log V), asymptotiquement meilleur sur les graphes denses, mais les constantes le rendent rarement rentable en pratique. Sur un graphe très dense, l'option la plus simple l'emporte: conserver un tableau de l'arête la moins chère connue vers chaque sommet extérieur et le parcourir à chaque tour donne O(V au carré), ce qui bat O(E log V) dès que E approche V au carré. Le choix de structure de données est donc dicté par la densité, pas par une préférence générale.
Prim et Kruskal produisent tous deux un arbre couvrant de poids minimum. Le bon choix dépend de la densité, de l'ordre d'arrivée des arêtes et de la connexité du graphe.
| Alternative | À préférer quand | Coût |
|---|---|---|
| Algorithme de Kruskal | Graphes creux, ou arêtes déjà triées par poids. Fait croître une forêt plutôt qu'un seul arbre, à l'aide d'Union-Find. | O(E log E) |
| Algorithme de Boruvka | Tu veux du parallélisme. Chaque composante choisit simultanément son arête sortante la moins chère. | O(E log V) |
| Prim avec parcours de tableau | Graphes denses où E approche V au carré. Évite entièrement le coût du tas. | O(V^2) |
| Algorithme de Dijkstra | Tu veux en réalité des plus courts chemins depuis une source, pas une structure couvrante de poids minimum. Forme voisine, objectif différent. | O((V + E) log V) |
Lire l'article complet: Prim's MST Algorithm Explained Step by Step
Lire l'article complet: Minimum Spanning Trees: Prim, Kruskal and Boruvka
Algorithmes associés: Algorithme de Kruskal, Algorithme de Borůvka, Algorithme de Dijkstra