Universit´e d’Aix-Marseille L2 Informatique - Math´ematiques 2016/2017
Algorithmique
TP 7 : algorithme de Dijkstra
Ce TP est consacr´e `a la programmation de l’algorithme de Dijkstra.
On enregistre un graphe orient´e pond´er´e sous forme d’un fichier ASCII dont
la premi`ere ligne contient le nombre de sommets du graphe
la seconde ligne contient le nombre d’arcs du graphe
chaque ligne suivante d´ecrit un arc sour la forme : sommet1, sommet2, poids
Dessinez le graphe correspondant au fichier suivant.
6
10
0 1 19
028
1 2 14
146
234
2 4 22
312
3 4 10
3 5 11
452
Un graphe sera repr´esent´e par un type structur´e comprenant deux champs :
nbSommets : le nombre de sommets du graphe
Adj : les listes d’adjacence du graphe.
Adj est un tableau d’´el´ements de type LISTE,o`uLISTE d´ecrit des listes chaˆın´ees de
couples (sommet,poids) ;Adj[v] est la liste des sommets adjacents au sommet v;
seules les nbSommets premi`eres cases de Adj sont pertinentes pour le graphe.
La fonction void litGraphe(char *adr, GRAPHE *G) saisit un graphe `a partir d’un
fichier.
#define POIDS_MAX 50 // poids maximum
#define NB_SOM_MAX 10 // nombre de sommets maximum
/* liste cha^ın´ee de couples (sommet, poids) */
typedef struct maillon{
struct maillon *suiv;
int nom;
int poids;
} MAILLON, *LISTE;
1
/* structure de graphe */
typedef struct graphe{
int nbSommets;
LISTE Adj[NB_SOM_MAX]; // liste d’adjacence
} GRAPHE;
/* pour charger un graphe `a partir d’un fichier */
void litGraphe(char *adr, GRAPHE *G){
FILE *f;
int sa,sb,pds,nbArcs;
f=fopen(adr,"r");
fscanf(f,"%d",&(G->nbSommets));
initAdjGraphe(G); // `a ´ecrire
fscanf(f,"%d",&nbArcs);
while (nbArcs){
fscanf(f,"%d %d %d",&sa,&sb,&pds);
insere(sa,sb,pds, G->Adj); // `a ´ecrire
nbArcs--;
}
fclose(f);
}
On pourra utiliser la fonction main suivante :
int main(void){
GRAPHE G;
litGraphe("./graphe.txt", &G);
afficheGraphe(G);
dijkstra(0, G);
return 0;
}
´
Ecrivez les fonctions suivantes :
1. /* ins`ere (som_b,poids) en t^ete dans la liste d’adjacence Adj[som_a] */
void insere(int som_a,int som_b, int poids, LISTE Adj[]){ ... }
2. /* initialisation de la table d’adjacence : toutes les listes cha^ın´ees
sont vides */
void initAdjGraphe(GRAPHE *G){ ... }
3. /* affichage d’un graphe : le nombre de sommets, puis
chaque arc pond´er´e : (sommet_1, sommet_2, poids) */
void afficheGraphe(GRAPHE G){ ... }
4. /* algorithme de Dijkstra : calcule (et affiche) les tableaux dist et pred */
void dijkstra(int s, GRAPHE G){...}
Dans un premier temps, vous pourrez impl´ementer l’ensemble Fdes sommets `a explo-
rer comme un tableau de G.nbSommets ´e l ´e m e n t s t e l s q u e F[i] = 1 si le sommet iest
dans Fet F[i] = 0 sinon.
2
5. Compl´etez l’algorithme pr´ec´edent pour qu’il ache les chemins les plus courts entre
s et tous les sommets de G (du coup, on n’aura plus besoin qu’il ache les tableaux
dist et pred. Pour cela, vous pourrez aussi ´ecrire des fonctions
int affiche plus court chemin(int s, int t, int pred[]) qui ache le plus
court chemin de s `a t et renvoie 0 s’il n’existe pas, et
void affiche plus courts chemins(int s, int nbSommets, int pred[], int
dist[]) qui ache tous les plus courts chemins `a partir de s, avec leur distance.
Plus court chemin de 2 `a 0 : sommet non atteint.
Plus court chemin de 2 `a 1 : 2 3 1 . Distance : 6
Plus court chemin de 2 `a 2 : 2 . Distance : 0
Plus court chemin de 2 `a 3 : 2 3 . Distance : 4
Plus court chemin de 2 `a 4 : 2 3 1 4 . Distance : 12
Plus court chemin de 2 `a 5 : 2 3 1 4 5 . Distance : 14
6. (dicile) Si l’on impl´emente Fcomme un tableau, la recherche du sommet i pour
lequel dist[i] est minimale est lin´eaire : d’o`u une complexit´e de O(n2) au total,
o`u n=G.nbSommets. Si l’on impl´emente Fcomme une file de priorit´e, c’est-`a-dire
un tasmin muni d’une fonctionnalit´e de mise `a jour, on obtient une complexit´e de
O(nlog n). ´
Ecrivez cette variante de l’algorithme de Dijkstra : void dijkstraFP(int
s, GRAPHE G). Pour cela,
vous introduirez les variables int f[NB SOM MAX], nf, ind f[NB SOM MAX],o`uf
repr´esente le tasmin prioritaris´e par dist 1,nf est le nombre d’´el´ements du tasmin
et ind f[i] donne l’indice du sommet idans le tasmin f;
la fonction int extrait min(int f[], int ind f[], int *nf, int dist[]) ex-
trait le min de f, c’est-`a-dire f[0], tout en pr´eservant la structure de tasmin et en
actualisant ind f
— la fonction void maintient(int f[], int ind f[], int i, int dist[]) qui
maintient la structure de fet la s´emantique de ind f lorsque dist[i] et´ediminu´e
pour un sommet ide f.
7. (dicile) La structure que nous avons consid´er´ee pour les listes d’adjacence est mi-
dynamique (les listes d’adjacences elles-mˆemes), mi-statique (on d´eclare un tableau de
NB SOM MAX listes d’adjacence). Comment faire en sorte que la structure soit totalement
dynamique, c’est-`a-dire ne d´epende pas de la constante NB SOM MAX ?
1. si iest un ascendant de j, alors dist[i]dist[j].
3
1 / 3 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !