Lycée Carnot — 2016-2017 Option informatique MP/MP* TP 8 : Algorithme de Prim pour les arbres couvrants On rappelle qu’un arbre est un graphe connexe sans cycle. Considérons un graphe G = (V, E) connexe. On peut pondérer les arêtes du graphe avec une fonction p : E → R, dite de pondération. Dans ce TP, le graphe G sera représenté par listes d’adjacence pondérées : G.(i ) contient la liste des sommets adjacents à i dans G avec le poids de l’arête associée : (int * int) list vect. On considère maintenant un graphe non orienté G connexe et pondéré à poids positifs. Un arbre couvrant du graphe G = (V, E) est un arbre A = (V, E0 ) connexe tel que E0 ⊂ E. L’objectif de ce TP est de trouver un arbre couvrant minimal (soit, de poids minimum) de G. 1 Description de l’algorithme de Prim L’algorithme de Prim construit un arbre couvrant minimal A en procédant de la façon suivante : • A un sommet s quelconque de V. • Parmi toutes les arêtes accessibles depuis A, on en extrait une de poids minimal. • Si elle relie deux sommets déjà ajoutés à l’arbre, on l’ignore, sinon on l’ajoute à A, on met à jour les arêtes accessibles depuis A et on retourne à l’étape précédente. Q UESTION 1 Montrer que cet algorithme termine. Pour l’implémenter, nous avons besoin d’une structure pour représenter l’ensemble des arêtes accessibles depuis A. Cette structure doit nous permettre efficacement : • d’y insérer de nouveaux éléments ; • et d’en extraire l’élément minimum. C’est ce que l’on appelle une file de priorité. Tout d’abord, nous allons simuler cette file de priorité avec une liste triée (pas très efficace) puis avec un tableau ayant une structure de tas. Voici un graphe sur lequel tester vos algorithmes : let graphe1 = [| [(1, 4); (7, 8)]; [(0, 4); (2, 8); (7, 11)]; [(1, 8); (3, 7); (5, 4); (8, 2)]; [(2, 7); (4, 9); (5, 14)]; [(3, 9); (5, 10)]; [(4, 10); (3, 14); (2, 4); (6, 2)]; [(5, 2); (8, 6); (7, 1)]; [(6, 1); (8, 7); (1, 11); (0, 8)]; [(2, 2); (6, 6); (7, 7)] |];; Deux arbres couvrants de poids minimaux pour ce graphe sont : let arbre1 = [|[1]; [2; 0]; [3; 5; 8; 1]; [4; 2]; [3]; [6; 2]; [7; 5]; [6]; [2]|] ;; let arbre2 = [|[7; 1]; [0]; [3; 8; 5]; [4; 2]; [3]; [2; 6]; [5; 7]; [6; 0]; [2]|] ;; http://carnot.cpge.info 1 Lycée Carnot — 2016-2017 2 Option informatique MP/MP* Implémentation de l’algorithme de Prim avec une liste triée Q UESTION 2 Écrire les fonctions insere et extrait_min pour une liste triée (avec une fonction de comparaison quelconque compare qui sera fournie en argument). Quelle sont leurs complexités ? Q UESTION 3 Écrire la fonction maj_accessibles qui, quand un sommet est ajouté à l’arbre, met à jour (à l’aide de la fonction insere) la liste triée des arêtes accessibles depuis A. On fera attention au fait que les listes d’adjacence contiennent des couples de la forme (sommet, poids) alors que la liste à mettre à jour possède des éléments de la forme (arete, poids). Q UESTION 4 Écrire une fonction prim1 qui implémente l’algorithme de Prim en utilisant une liste triée. Quelle est sa complexité ? 3 Implémentation de l’algorithme de Prim avec une file de priorité (un tas) Un tas-min est un arbre binaire qui vérifie les deux propriétés suivantes : • Chaque noeud a une valeur supérieure à celle de son père (la racine a donc la valeur minimale). • L’arbre est complet : pour un tas de taille n, si on numérote ses sommets par un parcours en largeur alors le père de i est en case [à compléter] et ses fils sont dans les cases [à compléter]. La taille du tas étant appelée à être modifiée, celui-ci est représenté par un couple (t, n) où t est un tableau de la taille maximale dont on aura besoin et n la taille réelle du tas : type tas = {mutable taille : int; mutable elements : ((int * int) * int) vect};; Q UESTION 5 Écrire une fonction qui transforme un tableau quelconque en tas-min. Vous vous aiderez d’une fonction entasser telle que entasser tas i suppose que les arbres enracinés en 2 ∗ i + 1 et 2 ∗ i + 2 dans le tas t sont bien des tas-min, et transforme le tableau pour que la propriété de tas-min soit vérifiée pour le tableau enraciné en i si elle n’est pas vérifiée. Q UESTION 6 Implémenter efficacement les fonctions insere_tas et extrait_min_tas pour un tas-min. Quelle sont leurs complexités ? Q UESTION 7 Écrire une fonction prim2 qui implémente l’algorithme de Prim en utilisant un tas-min. Quelle est sa complexité ? Q UESTION 8 Implémenter le tri par tas. http://carnot.cpge.info 2