Le TP est à rendre (par email) pour le mercredi 23 décembre à 8h00.
Pour ce TP comme pour les suivants, la pièce la plus importante sera un fichier tp2-nom-prenom.c
contenant votre programme. Le seul fait que votre programme fonctionne ne suffit pas pour avoir une bonne note. Les points suivants seront également pris en compte :
Les réponses aux questions posées dans le TP (complexité de vos fonctions par exemple) seront insérées comme commentaires dans votre fichier principal.
Attention : les points suivants ne rapportent rien, mais ne pas les respecter pourra retrancher jusqu'à 10 points sur la note finale :
-Wall -Werror -Wextra -pedantic -std=c99
.
Makefile
fourni comme pour le TP1. Il suffit de modifier la variable NOM
pour prendre en compte votre propre fichier.
Soit G un graphe orienté avec des poids (entiers) strictement positifs sur les arc ; soit entrée et sortie deux sommets particuliers de G.
Un flot de entrée vers sortie est la donnée, pour chaque arc e de G, d'un nombre entier f(e) qui satisfait les contraintes suivantes :
La valeur du flot est définie comme la somme précédente lorsque le sommet a est entrée. (C'est aussi l'opposé de la somme pour le sommet sortie.)
Le poids d'un arc est souvent appelé sa capacité.
On recherche le flot maximum qui peut traverser le graphe en entrant par le sommet entrée et en sortant par le sommet sortie.
Les applications sont nombreuses. Les sommets peuvent par exemple représenter des routeurs dans un réseau, des gares ferroviaire, des échangeurs autoroutiers, des robinets etc. ; les arcs peuvent être des câbles, des voies ferrées, des routes, des tuyaux etc.
Dans tous les cas, on essaie de maximiser la circulation d'une quantité entre deux noeuds.
Ce problème a une solution en temps « raisonnable », c'est à dire polynomiale en la taille du graphe de entrée. L'idée de l'algorithme est la suivante :
Comme pour les autres algorithmes, il faut faire une preuve mathématique que cette méthode abouti effectivement à un flot maximal. (La valeur du flot maximum est unique, mais il peut y avoir plusieurs flots avec cette même valeur.)
On peut se servir de graphes pour :
La recherche d'un chemin du sommet entrée vers le sommet sortie se fait simplement en cherchant un chemin dans le graphe résiduel. Pour cela, le plus simple est de faire un parcours en largeur de G\F. Une fois un tels chemin trouvé, on choisit de faire passer un flot égal poids minimal d'un arc de ce chemin. (C'est donc un flot maximal pour ce chemin.)
Remarque : le graphe résiduel peut contenir des arcs qui ne sont pas présents dans le graphe G. C'est par exemple le cas quand il y un arc de u vers v mais pas de v vers u. Si le flot f(u,v) est positif, alors c(v,u) - f(v,u) = 0 + f(u,v) est positif. Un tels arc représente en fait la possibilité de diminuer le flot dans l'arc (u,v)...
Programmez la fonction de prototype
int flotMaximal(GrapheListe G, int entree, int sortie, GrapheListe Flot) ;
Cette fonction renvoie la valeur du flot maximal trouvé et stocke le flot en question dans le graphe Flot
.
Essayer d'estimer la complexité de votre algorithme.
Conseils : réfléchissez avant à la représentation des graphes que vous voulez utiliser et aux fonctions auxiliaires dont vous aurez besoin.