MP option informatique Exercice 12 (Algorithme de Kruskal

publicité
MP option informatique
1)
Exercice 12 (Algorithme de Kruskal)
Graphes
a) Le graphe G étant connexe, on peut considérer l’ensemble de ses sous-graphes connexes qui ne
sera pas vide (mais est fini). On considère dans cet ensemble un sous-graphe qui a le moins
d’arêtes. Il est nécessairement acyclique car s’il avait un cycle, on pourrait enlever une arête sans
” casser ” la connexité.
b) A tout moment le sous-graphe (V, Ek ) est acyclique par définition.
Montrons que le graphe final (noté Gf = (V, Ef )) est connexe. Par l’absurde, supposons qu’il ne
le soit pas. On considère alors deux composantes connexes de Gf . Elles sont reliés par un chemin
(dans G). Soit e une arête de G qui ” sort ” d’une composante connexe (il suffit de prendre la
première arête du chemin considéré ci-dessus). De ce fait, ajouter e à Gf ne va pas créer un cycle
- cela signifie qu’au moment où on a considéré e (pour ne pas l’ajouter) elle ne créait pas de cycle.
C’est donc absurde.
Finalement Gf est bien un arbre.
2) L’ensemble des arbres couvrant est un sous-ensemble de l’ensemble des sous-graphes. Il est donc fini.
Il y a donc des arbres couvrants de poids minimal.
3)
a) b) Considérons C1 , . . . , Cp les composantes connexes de (V, E1 ).
• S’il existe une arête de E2 qui connecte deux composantes connexes distinctes alors on peut
ajouter cette arête sans créer un cycle.
• Supposons à l’inverse que toute arête de E2 connecte deux sommets d’une même composante
connexe. Comme |E2 | > |E1 | il existe une des composantes connexe où il y a (strictement)
plus d’arêtes de E2 que de E1 . En se restreignant à cette composante connexe, on voit que
E1 engendre un arbre (connexe et sans cycle). Il ne se peut donc pas que E2 ait plus d’arêtes.
On ne peut finalement pas être dans ce cas.
c) Montrons par récurrence sur k que pour tout arbre couvrant T de poids minimal, la somme des
poids des k arêtes les plus légères de T est supérieure ou égale à la somme des k arêtes de l’arbre
renvoyé par l’algorithme.
Fixons les notations. On pose (e1 , . . . , em ) les arêtes du graphes (classées par poids croissant).
On note i1 ≤ i2 ≤ · · · ≤ in−1 les indices des arêtes dans T et j1 ≤ · · · ≤ jn−1 les arêtes du graphe
renvoyé par l’algorithme.
• Initialisation : Pour k = 0 c’est vrai
• Hérédité : on suppose que la propriété est vraie pour un k donné. C’est-à-dire que
p(ej1 ) + · · · + p(ejk ) ≤ p(ei1 ) + · · · + p(eik )
D’après la question précédente, on sait qu’il existe une arête eα dans {ei1 , . . . , eik+1 } \
{ej1 , . . . , ejk } telle que si on l’ajoute à {ej1 , . . . , ejk } on obtient un graphe sans cycle. Comme
elle n’a de fait pas été ajoutée alors
p(ejk ) ≤ p(eα )
De ce fait, p(ejk+1 ) ≤ p(eα ). On a donc
p(ej1 ) + · · · + p(ejk+1 ) ≤ p(ei1 ) + · · · + p(eik ) + p(eα ) ≤ p(ei1 ) + · · · + p(eik+1 )
car p(eα ) ≤ p(eik+1 ).
Lycée Chateaubriand
1/3
MP option informatique
Exercice 12 (Algorithme de Kruskal)
Graphes
d) On implémente l’algorithme de Kruskal. Il faut d’abord construire la liste des arêtes triées selon
leur poids. On construit cette liste par :
let creeListeArete g =
let n = vect_length g in
let rec ajoute l i =
match i , l with
| i , [] when i = n -> []
| i , [] -> ajoute g .( i + 1) ( i + 1)
| i ,( j , p ) :: q -> (p , i , j ) :: ajoute q i
in
ajoute g .(0) 0;;
qui permet de créer une liste des arêtes sous la forme de triplets : poids, debut, fin.
On peut alors faire (par exemple) un tri fusion
let rec division liste =
match liste with
|[] - >[] ,[]
| a ::[] - > liste ,[]
| a :: b :: c - >
let ( l1 , l2 ) = division c in
a :: l1 , b :: l2 ;;
let rec fusionTri liste1 liste2 =
match liste1 , liste2 with
|[] , _ - > liste2 ;
|_ ,[] - > liste1 ;
|( p1 , i1 , j1 ) :: q1 , ( p2 , i2 , j2 ) :: q2 - >
if p1 < p2 then
( p1 , i1 , j1 ) ::( fusionTri q1 liste2 )
else
( p2 , i2 , j2 ) ::( fusionTri liste1 q2 ) ;;
let rec tri_fusion liste =
match liste with
|[] - >[];
| a ::[] - > liste ;
| _ ->
begin
let ( liste1 , liste2 ) = division liste in
fusionTri ( tri_fusion ( liste1 ) ) ( tri_fusion ( liste2 ) ) ;
end ;;
Lycée Chateaubriand
2/3
MP option informatique
Exercice 12 (Algorithme de Kruskal)
Graphes
Il ne reste plus qu’à écrire le programme en utilisant la structure Union-Find.
let kruskal g =
let listeArete = tri_fusion ( creeListeArete g ) in
let n = vect_length g in
let t = creer2 n in
let rec traiteListe l = match l with
| [] -> []
| (p , i , j ) :: q -> if representant2 t i = representant2 t j
then traiteListe q
else ( fusion2 t i j ;
(p , i , j ) :: traiteListe q )
in
traiteListe listeArete ;;
Lycée Chateaubriand
3/3
Téléchargement