Professional Documents
Culture Documents
CHAPITRE 39
GEN-3405
39-1 Dfinition
Un arbre de recouvrement est un graphe partir duquel on a enlev certaines artes pour viter tout cycle et ainsi former un arbre. Ce genre dopration sur les graphes pour trouver larbre de recouvrement est utile par exemple dans l'analyse des circuits lectriques. Dans tel circuit, les noeuds sont les points de jonction des composants, et les artes sont constitues par les lments diplaires (rsistances, condensateurs, inductances, source de courant, source de tension) qui relient 2 noeuds. La pondration des artes est tout simplement la valeur physique de llment reliant les noeuds.
Thorme:
Dans un arbre de recouvrement minimum, tout partage de larbre en 2 sous-arbres contient larte minimum qui reliait les 2 sous-arbres.
CHAPITRE 39
Algorithme:
Tant quil reste des sommets dans la liste de priphrie. | Trouver le sommet dans la liste de priphrie qui possde | le moindre cot de lien avec larbre | Relier ce sommet larbre de recouvrement minimum (ARM) | Mettre jour la liste des sommets de la priphrie. Fin.
GEN-3405
} Noeud_periphrique; Noeud_peripherique *tete_peri = NULL; //---------------------------------------------------------// fonction principale pour la construction de larbre // recouvrement minimal (ARM). // void Arm(Noeud *premier_noeud) { Noeud *courant; Noeud_adjacent *adj_courant; //insre le premier sommet dans la liste priphrique. insere_sommet(premier_noeud, 0); //dtermine le sommet au meilleur cot dans la liste priphrique //et rattache le lARM. met jour la liste priphrique. do { courant = retire_sommet(); courant->parcouru = VRAI; //examen de la liste d'adjacence pour insertion de //nouveaux noeuds dans la liste priphrique. for (adj_courant = courant->premier_adj; adj_courant != NULL; adj_courant = adj_courant->suivant;) { // si le noeud nappartient pas dj lARM, // linsrer dans la liste priphrique. if (adj_courant->identite_noeud->parcouru = FAUX) status = insere_sommet(adj_courant->identite_noeud, adj_courant->cout); //finaliser la connexion lARM. if (status = VRAI) adj_courant->identite_noeud->pere = courant; } } while (tete_peri != NULL) } //--------------------------------------------------------------// fonction pour ajouter un sommet la liste priphrique. // int insere_sommet(Noeud *a_inserer, int cout) { Noeud_peripherique *prec, *courant, *nouveau; //localiser la position dinsertion prec = NULL; courant = tete_peri; while (courant !=NULL && courant->identite_noeud != a_inserer) { prec = courant; courant = courant->suivant; } //vrifier si le noeud tait dj dans la liste //auquel cas rafraichir son cot. if (courant !=NULL && courant->identite_noeud == a_inserer) { if (courant->cout > cout) { courant->cout = cout; return VRAI;
CHAPITRE 39
} else { return FAUX; } } //sinon crer le nouveau noeud de la priphrie. if ( (nouveau = (Noeud_peripherique) malloc(sizeof(Noeud_peripherique)) == NULL) { printf(\nEspace mmoire insuffisant pour crer le noeud periphrique); exit(1); } //remplir la structure Noeud_peripherique. nouveau->cout = cout; nouveau->identite_noeud = a_inserer; nouveau->peri_suivant = NULL; //insrer dans liste des noeuds priphriques if (prec == NULL) tete_peri = nouveau; else peri->peri_suivant = nouveau; return VRAI; } //--------------------------------------------------------------// fonction pour extraire un sommet de la liste des noeuds // priphrique et possdant le moindre cot. // Noeud *retire_sommet(void) { Noeud_peripherique *prec = NULL; Noeud_peripherique *meilleur = tete_peri; Noeud_peripherique *prec_meilleur = NULL; Noeud_peripherique *a_retirer = tete_peri; Noeud *noeud_a_retourner; // trouver le sommet avec le moindre cot dans la liste priphrique. while (a_retirer != NULL) { if (meilleur->cout > a_retirer->cout) { meilleur = a_retirer; prec_meilleur = prec; } prec = a_retirer; a_retirer = a_retirer->peri_suivant; } noeud_a_retourner = meilleur->identite_noeud; // effectue le recollement dans la liste des noeuds // priphriques aprs le retrait dun noeud cot minimum. if (prec_meilleur != NULL) //si llment ntait pas en dbut de liste prec_meilleur->peri->suivant = meilleur->peri_suivant; else // llment tait en dbut de liste tete_peri = meilleur->peri_suivant; free(meilleur); //libre lespace. return noeud_a_retourner; }
GEN-3405
//-----------------------------------------------------------------....
Structures
Noeud
valeur mot parcouru *pre *premier_adj
Graphe initial
3 Berri
3 1 3 7 5
9 Sauv
1
23 Peel
2 4
32 Jarry
6
99 Monk
6 5
13 Guy
Noeud_adjacent
cout *identite_noeud *adj_suivant
10
3
17 Viau
56 Pie-IX
Noeud_peripherique
cout *identite_noeud *peri_suivant
Figure 39-2.
ARM en construction
Peel est dans lARM
3 Berri
3 1 3 7 5
9 Sauv
1
23 Peel
2 4
32 Jarry
6
99 Monk
6 5
13 Guy
10
3
17 Viau
56 Pie-IX
Liste priphrique
*tete_peri
1 Berri 4 Jarry 10 Viau
Figure 39-1.
CHAPITRE 39
ARM en construction
Peel et Berri sont dans lARM
3 Berri
3 1 3 7 5
9 Sauv
1
23 Peel
2 4
32 Jarry
6
99 Monk
6 5
13 Guy
10
3
17 Viau
56 Pie-IX
Liste priphrique
*tete_peri
2 Jarry 10 Viau 3 Sauv
Figure 39-3.
ARM en construction
Peel, Berri et Jarry sont dans lARM
3 Berri
3 1 3 7 5
9 Sauv
1
23 Peel
2 4
32 Jarry
6
99 Monk
6 5
13 Guy
10
3
17 Viau
56 Pie-IX
Liste priphrique
*tete_peri
3 Viau 1 Sauv 3 Monk 7 Pie-IX
Figure 39-4.
GEN-3405
ARM en construction
Peel, Berri, Jarry et Sauv sont dans lARM
3 Berri
3 1 3 7 5
9 Sauv
1
23 Peel
2 4
32 Jarry
6 6
99 Monk
13 Guy
10
3
17 Viau
56 Pie-IX
Liste priphrique
*tete_peri
3 Viau 3 Monk 7 Pie-IX 6 Guy
Figure 39-5.
ARM en construction
Peel, Berri, Jarry, Sauv et Viau sont dans lARM
3 Berri
3 1 3 7 5
9 Sauv
1
23 Peel
2 4
32 Jarry
6 6
99 Monk
13 Guy
10
3
17 Viau
56 Pie-IX
Liste priphrique
*tete_peri
3 Monk 5 Pie-IX 6 Guy
Figure 39-6.
CHAPITRE 39
ARM en construction
Peel, Berri, Jarry, Sauv Viau et Monk sont dans lARM
3 Berri
3 1 3 7 5
9 Sauv
1
23 Peel
2 4
32 Jarry
6 6
99 Monk
13 Guy
10
3
17 Viau
56 Pie-IX
Liste priphrique
*tete_peri
5 Pie-IX 5 Guy
Figure 39-7.
10
GEN-3405
// //structure de liste pour les noeuds ou sommets. typedef struct tagNoeud { int valeur; char mot[MAX]; int parcouru; int temps; struct TagNoeud *pere; struct TagNoeud *suivant; struct TagNoeud_adj *premier_adj; } Noeud; // structure de liste pour les listes dadjacence. typedef struct tagNoeud_adj { int cout; tagNoeud *identite_noeud; struct tagNoeud_adj *adj_suivant; } Noeud_adjacent; // structure de liste pour la liste des noeuds priphriques. typedef struct tagNoeud_peripherique{ int cout; Noeud *identite_noeud; struct tagNoeud_peripherique *peri_suivant; } Noeud_periphrique; Noeud_peripherique *tete_peri = NULL; //---------------------------------------------------------// fonction principale pour la construction de larbre // chemins minimum (ACM). // void ACM(Noeud *premier_noeud) { Noeud *courant; Noeud_adjacent *adj_courant; //insre le premier sommet dans la liste priphrique. insere_sommet(premier_noeud, 0); //dtermine le sommet au meilleur cot dans la liste priphrique //et rattache le lACM. met jour la liste priphrique. do { courant = retire_sommet(); courant->parcouru = VRAI; //examen de la liste d'adjacence pour insertion de //nouveaux noeuds dans la liste priphrique. for (adj_courant = courant->premier_adj; adj_courant != NULL; adj_courant = adj_courant->suivant;) { // si le noeud nappartient pas dj lACM, // linsrer dans la liste priphrique. if (adj_courant->identite_noeud->parcouru = FAUX) status = insere_sommet(adj_courant->identite_noeud, adj_courant->cout+courant->temp); //finaliser la connexion lACM. if (status = VRAI) adj_courant->identite_noeud->pere = courant; } } while (tete_peri != NULL)
11
CHAPITRE 39
} //--------------------------------------------------------------// fonction pour ajouter un sommet la liste priphrique. // int insere_sommet(Noeud *a_inserer, int nouveau_temps) { Noeud_peripherique *prec, *courant, *nouveau; //localiser la position dinsertion prec = NULL; courant = tete_peri; while (courant !=NULL && courant->identite_noeud != a_inserer) { prec = courant; courant = courant->suivant; } //vrifier si le noeud tait dj dans la liste //auquel cas rafraichir son temps. if (courant !=NULL && courant->identite_noeud == a_inserer) { if (courant->identite_noeud->temps > nouveau_temps) { courant->identite_noeud->temps = nouveau_temps; return VRAI; } else { return FAUX; } } //sinon crer le nouveau noeud de la priphrie. if ( (nouveau = (Noeud_peripherique) malloc(sizeof(Noeud_peripherique)) == NULL) { printf(\nEspace mmoire insuffisant pour crer le noeud periphrique); exit(1); } //remplir la structure Noeud_peripherique. nouveau->identite_noeud = a_inserer; nouveau->identite_noeud->temps = nouveau_temps; nouveau->peri_suivant = NULL; //insrer dans liste des noeuds priphriques if (prec == NULL) tete_peri = nouveau; else peri->peri_suivant = nouveau; return VRAI; } //--------------------------------------------------------------// fonction pour extraire un sommet de la liste des noeuds // priphrique et possdant le moindre cot. // Noeud *retire_sommet(void) { Noeud_peripherique *prec = NULL; Noeud_peripherique *meilleur = tete_peri; Noeud_peripherique *prec_meilleur = NULL; Noeud_peripherique *a_retirer = tete_peri; Noeud *noeud_a_retourner;
12
GEN-3405
// trouver le sommet avec le moindre temps dans la liste priphrique. while (a_retirer != NULL) { if (meilleur->identite_noeud->temps > a_retirer->identite_noeud->temps) { meilleur = a_retirer; prec_meilleur = prec; } prec = a_retirer; a_retirer = a_retirer->peri_suivant; } noeud_a_retourner = meilleur->identite_noeud; // effectue le recollement dans la liste des noeuds // priphriques aprs le retrait dun noeud temps minimum. if (prec_meilleur != NULL) //si llment ntait pas en dbut de liste prec_meilleur->peri->suivant = meilleur->peri_suivant; else // llment tait en dbut de liste tete_peri = meilleur->peri_suivant; free(meilleur); //libre lespace. return noeud_a_retourner; } //-----------------------------------------------------------------
Structures
Noeud
valeur mot parcouru temps *pre *premier_adj
Graphe initial
3 Berry infini
3 1 3 7 5
9 Sauv infini
1
23 Peel 0
2 4
32 Jarry infini
6
99 Monk infini
6 5
13 Guy infini
Noeud_adjacent
cout *identite_noeud *adj_suivant
3 10
17 Viau infini
Noeud_peripherique
cout *identite_noeud *peri_suivant
56 Pie-IX infini
Figure 39-8.
13
CHAPITRE 39
ACM en construction
Peel est dans lACM
3 Berry 0+1
3 1 3 7 5
9 Sauv infini
1
23 Peel 0
2 4
32 Jarry 0+4
6
99 Monk infini
6 5
13 Guy infini
3 10
17 Viau 0+10
56 Pie-IX infini
Liste priphrique
*tete_peri
1 Berri 4 Jarry 10 Viau
Figure 39-9.
ACM en construction
Peel et Berry sont dans lACM
3 Berry 1
3 1 3 7 5
9 Sauv 1+3
1
23 Peel 0
2 4
32 Jarry 1+2
6
99 Monk infini
6 5
13 Guy infini
3 10
17 Viau 0+10
56 Pie-IX infini
Liste priphrique
*tete_peri
2 Jarry 10 Viau 3 Sauv
Figure 39-10.
14
GEN-3405
ACM en construction
Peel, Berry et Jarry sont dans lACM
3 Berry 1
3 1 3 7 5
9 Sauv 1+3
1
23 Peel 0
2 4
32 Jarry 3
6
99 Monk 3+3
6 5
13 Guy infini
3 10
17 Viau 3+3
56 Pie-IX 3+7
Liste priphrique
*tete_peri
3 Viau 3 Sauv 3 Monk 7 Pie-IX
Figure 39-12.
ACM en construction
Peel, Berry Jarry et Sauv sont dans lACM
3 Berry 1
3 1 3 7 5
9 Sauv 4
1
23 Peel 0
2 4
32 Jarry 3
6
99 Monk 3+3
6 5
13 Guy 4+6
3 10
17 Viau 3+3
56 Pie-IX 3+7
Liste priphrique
*tete_peri
3 Viau 3 Monk 7 Pie-IX 6 Guy
Figure 39-11.
15
CHAPITRE 39
ACM en construction
Peel, Berry Jarry, Sauv et Viau sont dans lACM
3 Berry 1
3 1 3 7 5
9 Sauv 4
1
23 Peel 0
2 4
32 Jarry 3
6
99 Monk 3+3
6 5
13 Guy 4+6
3 10
17 Viau 6
56 Pie-IX 3+7
Liste priphrique
*tete_peri
3 Monk 7 Pie-IX 6 Guy
Figure 39-13.
ACM en construction
Peel, Berry Jarry, Sauv Viau et Monk sont dans lACM
3 Berry 1
3 1 3 7 5
9 Sauv 4
1
23 Peel 0
2 4
32 Jarry 3
6
99 Monk 6
6 5
13 Guy 4+6
3 10
17 Viau 6
56 Pie-IX 3+7
Liste priphrique
*tete_peri
7 Pie-IX 6 Guy
Figure 39-14.
16
GEN-3405
ACM en construction
Peel, Berry Jarry, Sauv Viau, Monk et Pie-IX sont dans lACM
3 Berry 1
3 1 3 7 5
9 Sauv 4
1
23 Peel 0
2 4
32 Jarry 3
6
99 Monk 6
6 5
13 Guy 4+6
3 10
17 Viau 6
56 Pie-IX 10
Liste priphrique
*tete_peri
6 Guy
Figure 39-15.
ARM en construction
Peel, Berri, Jarry, Sauv Viau , Monk et Pie-IX sont dans lARM
3 Berri
3 1 3 7 5
9 Sauv
1
23 Peel
2 4
32 Jarry
6 6
99 Monk
13 Guy
10
3
17 Viau
56 Pie-IX
Liste priphrique
*tete_peri
4 Guy
Figure 39-16.
17
CHAPITRE 39
ACM en construction
Tous les noeuds` Peel, Berry Jarry, Sauv Viau, Monk Pie-IX et Guy sont dans lACM
23 Peel 0 3 Berry 1
3 1 3 7 5
9 Sauv 4
1 4
2
32 Jarry 3
6
99 Monk 6
6 5
13 Guy 4+6
3 10
17 Viau 6
56 Pie-IX 10
Liste priphrique
*tete_peri NULL
Figure 39-17.
18
GEN-3405
QUESTIONS ET PROBLMES
C
19