Un graphe est un couple où
est un ensemble et
une relation sur
. Les éléments de
sont dits sommets, les couples en relation sont joints
par un arc. Le graphe est non orienté si on suppose la relation symétrique.
Il est acyclique s'il n'y a pas de cycle, c'est-à-dire qu'il n'existe pas
de liste
de sommets distincts telle que
soit relié à
pour tout
et
relié à
.
Théorème : On a alors l'équivalence des définitions suivantes :
Preuve :
(vi) (i) : Si
est non connexe,
et
sont non reliés. Alors, l'ajout de l'arête
ne le rendrait pas non acyclique, d'où une contradiction.
(i) (ii) : L'existence d'un chemin injectif résulte
de connexe (il existe un chemin) et de la finitude (on prend un chemin de longueur
minimum, il est « donc » injectif). Si on a deux chemins injectifs
et
joignant
qui divergent au
-ième sommet, on peut définir :
(
existe car
). On a un unique
tel que
et on a ainsi constitué un cycle
, d'où une contradiction.
(ii) (iii) :
est connexe par l'existence d'un chemin et si l'on
supprime l'arête
, alors on ne peut plus joindre
à
à cause de l'unicité du chemin entre les sommets.
(iii) (iv) : Une relation symétrique est un ensemble
de cases cochées dans un tableau (une partie de
).
Soit
le nombre de sommets et
le nombre d'arcs.
Si on avait , une colonne serait vide et le graphe non connexe. On a donc
. Prouvons
par récurrence sur le nombre de sommets
: la relation est vraie pour
. Soit
un graphe à
sommets. En ôtant une arête, on le déconnexifie. On obtient
composantes connexes (
) qui vérifient toutes les hypothèses de (iii) et ont au maximum
sommets. Pour chacune,
. On somme ces relations et en ajoutant l'arête enlevée au début,
on obtient la relation pour
.
(iv) (v) : On a
connexe et
. On veut
acyclique.
S'il existe un cycle , il a
arêtes et
sommets donc
. Il existe donc un
sommet qui n'est pas dans
et comme
est connexe, il existe un sommet adjacent. Mais ce
nouveau
vérifie les mêmes hypothèses : on
recommence jusqu'à avoir
en totalité et
, d'où une contradiction.
(v) (vi) :
a
composantes connexes et chacune vérifie donc
car ce sont des arbres.
On ajoute et on a donc
:
est donc connexe.
On a donc (i), donc (ii), donc si on ajoute une arête, on crée un cycle.
Pour savoir si (S1,...,Sn)
est connexe (Sk
sommets du graphe), on définit la liste
[V1;...;Vn]
des voisins de Sk
. On initialise un tableau de n booléens et on met le premier
à true
, car S1
touche S1
. Puis, on met à true tous ceux que Sk
touche en
enregistrant ceux que l'on n'a jamais vus dans une liste. On recommence avec les nouveaux tant que la
listen'est pas vide. Quand elle est vide, on regarde si tous les éléments du tableau ont la valeur
true
.
Cette méthode donne le test décrit par le PROGRAMME 2.3. La fonction
traite
permet de savoir s'il existe dans tab
un élément qui n'a pas la valeur
true
. La fonction cree_voisins
rend la liste des voisins de t
. Les fonctions
union
et subtract
sont des fonctions définis dans CAML qui réalisent l'union et
la différence de deux listes au sens ensembliste.
Pour créer l'arbre, on définit la matrice de voisinage du graphe : un élément v.(i).(j)
est
initialisé à 1
si les sommets i
et j
sont reliés, 0
sinon. On part alors de
la racine du futur arbre et on définit ses fils comme étant ses voisins. On « coche » les voisins dans la
matrice en transformant, sur la ligne qui leur correspond, les 1
en 2
. Puis on recommence avec
les fils de la racine. On obtient alors la fonction de transformation d'un graphe en arbre
(cf. PROGRAMME 2.5).