Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
| tc_info:2020_td-tp_flo [2020/08/08 17:09] – pprea | tc_info:2020_td-tp_flo [2020/10/01 14:03] (Version actuelle) – pprea | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| + | ===== TD-TP sur les Flots ===== | ||
| + | ~~NOTOC~~ | ||
| + | |||
| + | |||
| + | Ce " | ||
| + | |||
| + | Il n'est pas nécessaire de faire tout le TD avant d' | ||
| + | |||
| + | < | ||
| + | On considère un graphe orienté $G=(V,A)$ tel qu'à chaque arc (arête orientée) $u$ soit associé un nombre positif $c_u$, la **capacité** de $u$. | ||
| + | Un **flot (réalisable)** est une suite $\Phi = (\phi_u, u\in A)$ telle que : | ||
| + | * $\Phi$ est compatible avec les capacités : $\forall u \in A, 0\leq \phi_u \leq c_u$ | ||
| + | * $\Phi$ respecte la loi de Kirchoff (ou loi des nœuds) : $\forall v \in V, \sum_{u \in \Gamma^+(v)}{\phi_u} = \sum_{u \in \Gamma^-(v)}{\phi_u}$ \\ $\Gamma^+(v)$ est l' | ||
| + | |||
| + | Étant donnés deux sommets $s$ & $p$ (la **source** & le **puit**), le problème du **flot maximum** est de faire passer le plus grand flot de $s$ à $p$. | ||
| + | |||
| + | Pour se faire une idée un peu plus concrète que ce qu'est un flot, on peut imaginer chaque arc comme un tuyau à sens unique (en fait, cette restriction n'est pas nécessaire — cf Exercice 3) ayant un débit maximum (sa capacité), le problème étant de faire passer le plus de liquide possible de la //source// au //puit//. | ||
| + | |||
| + | L' | ||
| + | |||
| + | </ | ||
| + | |||
| + | ==== Partie TD ==== | ||
| + | |||
| + | L' | ||
| + | |||
| + | === 1. Un algorithme de flot === | ||
| + | |||
| + | Tout d' | ||
| + | [[tc_info: | ||
| + | |||
| + | < | ||
| + | Étant donné un flot $\Phi$ sur un graphe $G=(V,A)$, on considère le **graphe d' | ||
| + | |||
| + | Les capacités des arcs $u^+$ & $u^-$ sont appelées **capacités résiduelles**, | ||
| + | Remarquer que diminuer le flux sur l'arc $u=(x,y)$ d'une quantité $q$ revient à ajouter un flux de valeur $q$ dans le sens $(y, | ||
| + | |||
| + | En fait, dans le graphe d' | ||
| + | </ | ||
| + | |||
| + | À quoi correspond un chemin de de $s$ à $p$ dans $G_\Phi$ ? [[tc_info: | ||
| + | |||
| + | En déduire un algorithme de flux maximum. [[tc_info: | ||
| + | |||
| + | |||
| + | === 2. Mariages === | ||
| + | |||
| + | Une agence matrimoniale a, comme clients, $n$ hommes & $p$ femmes. Parmi les $n\times p$ couples homme-femme((Il est tout à fait possible de considérer d' | ||
| + | |||
| + | On modélisera ce problème par un flot maximum dans un graphe que l'on déterminera. [[tc_info: | ||
| + | |||
| + | |||
| + | === 3. Graphes non orientés === | ||
| + | |||
| + | Montrez que l' | ||
| + | [[tc_info: | ||
| + | |||
| + | |||
| + | === 4. La bataille de la Marne === | ||
| + | |||
| + | On a un ensemble $S$ de villes & des routes reliant certaines villes entre elles (il peut exister plusieurs routes entre deux villes). Chaque ville $i$ est caractérisée par un nombre $p_i$ de places de parking, & chaque route $j$ par une longueur $l_j$ (le temps pour aller d'une extrémité à l' | ||
| + | |||
| + | Au temps $t=0$, un certain de nombre de véhicules sont stationnés dans différentes villes ; il faut qu'au temps $t=K$, le plus possible de véhicules soient arrivés à une ville donnée (la Marne). Il est possible que des véhicules arrivent avant cette date butoir, mais après la date $K$, c'est trop tard. | ||
| + | |||
| + | On modélisera ce problème par un flot maximum dans un graphe que l'on déterminera. | ||
| + | [[tc_info: | ||
| + | |||
| + | |||
| + | === 5. Des extensions === | ||
| + | |||
| + | < | ||
| + | On peut supposer que chaque arc $u$ a une capacité minimum $c_u$ & une capacité maximum $c^u$ (on doit avoir $c_u\leq \phi_u \leq c^u$). Le problème est alors de trouver un flux **compatible** (qui n' | ||
| + | |||
| + | On peut aussi supposer que chaque arc prélève un " | ||
| + | </ | ||
| + | |||
| + | Montrez que la problème du plus court chemin (entre deux sommets $x$) & $y$ dans un graphe valué peut se modéliser par un problème de flux compatible à coût minimum dans un graphe que l'on déterminera. [[tc_info: | ||
| + | |||
| + | === 6. Un théorème === | ||
| + | |||
| + | Si toutes les capacités sont des entiers, que peut-on dire des flots maximums? [[tc_info: | ||
| + | |||
| + | |||
| + | ==== Partie TP ==== | ||
| + | |||
| + | |||
| + | On va maintenant implémenter (presque tout) ce qui a été vu dans la partie TD. | ||
| + | |||
| + | |||
| + | <note important> | ||
| + | Le fait de tester toutes vos créations n'est plus explicitement demandé car cela doit **encore & toujours** être fait. | ||
| + | </ | ||
| + | |||
| + | === 1. Implémentation des graphes === | ||
| + | |||
| + | < | ||
| + | Les graphes seront représentés " | ||
| + | |||
| + | <code python> | ||
| + | |||
| + | CAPACITE = " | ||
| + | FLUX = " | ||
| + | |||
| + | the_graph = {1: {2: {CAPACITE: 5, FLUX: 2}, 3: | ||
| + | 2: {3: {CAPACITE: 7, FLUX: 1}, 4: {CAPACITE: 8, FLUX: 1}}, | ||
| + | 3: {5: {CAPACITE: 4, FLUX: 2}}, | ||
| + | 4: {6: {CAPACITE: 3, FLUX: 2}}, | ||
| + | 5: {4: {CAPACITE: 6, FLUX: 1}, 6: {CAPACITE: 8, FLUX: 1}}, | ||
| + | 6: {} | ||
| + | } | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | Dessinez le graphe ci-dessus. | ||
| + | [[tc_info: | ||
| + | |||
| + | |||
| + | === 2. L' | ||
| + | |||
| + | Implémentez l' | ||
| + | : | ||
| + | |||
| + | <code python> | ||
| + | import math | ||
| + | |||
| + | INFINI = math.inf | ||
| + | CAPACITE = " | ||
| + | FLUX = " | ||
| + | |||
| + | |||
| + | def mise_a_zero_flot(graph): | ||
| + | for sommet in graph: | ||
| + | for voisin in graph[sommet]: | ||
| + | graph[sommet][voisin][FLUX] = 0 | ||
| + | |||
| + | |||
| + | def construction_graphe_ecart(graphe_antisymetrique): | ||
| + | graphe_ecart = {} | ||
| + | for sommet in graphe_antisymetrique: | ||
| + | graphe_ecart[sommet] = {} | ||
| + | for sommet in graphe_antisymetrique: | ||
| + | for voisin in graphe_antisymetrique[sommet]: | ||
| + | capacite = graphe_antisymetrique[sommet][voisin][CAPACITE] | ||
| + | flux = graphe_antisymetrique[sommet][voisin][FLUX] | ||
| + | if capacite > flux: | ||
| + | graphe_ecart[sommet][voisin] = capacite - flux | ||
| + | if flux > 0: | ||
| + | graphe_ecart[voisin][sommet] = flux | ||
| + | return graphe_ecart | ||
| + | |||
| + | |||
| + | def construction_chemin_via_dfs(graphe_ecart, | ||
| + | sommets_marques = {} | ||
| + | antecedents = {} | ||
| + | pile = [source] | ||
| + | for sommet in graphe_ecart: | ||
| + | antecedents[sommet] = None | ||
| + | while pile != []: | ||
| + | sommet = pile.pop() | ||
| + | if sommet not in sommets_marques: | ||
| + | sommets_marques[sommet] = True | ||
| + | for voisin in graphe_ecart[sommet]: | ||
| + | if voisin not in sommets_marques: | ||
| + | antecedents[voisin] = sommet | ||
| + | pile.append(voisin) | ||
| + | if sommet == puits: | ||
| + | return construction_effective_chemin(sommet, | ||
| + | |||
| + | |||
| + | def construction_effective_chemin(sommet, | ||
| + | chemin = [] | ||
| + | while sommet is not None: | ||
| + | chemin.append(sommet) | ||
| + | sommet = antecedents[sommet] | ||
| + | chemin.reverse() | ||
| + | return | ||
| + | |||
| + | |||
| + | def min_sur_chemin(chemin, | ||
| + | minimum = INFINI | ||
| + | for i in range(len(chemin) - 1): | ||
| + | courant = chemin[i] | ||
| + | suivant = chemin[i + 1] | ||
| + | if graphe_ecart[courant][suivant] < minimum: | ||
| + | minimum = graphe_ecart[courant][suivant] | ||
| + | return minimum | ||
| + | |||
| + | |||
| + | def ajout_flot(valeur, | ||
| + | for i in range(len(chemin) - 1): | ||
| + | courant = chemin[i] | ||
| + | suivant = chemin[i + 1] | ||
| + | if suivant in graphe_antisymetrique[courant]: | ||
| + | graphe_antisymetrique[courant][suivant][FLUX] += valeur | ||
| + | else: | ||
| + | graphe_antisymetrique[suivant][courant][FLUX] -= valeur | ||
| + | |||
| + | </ | ||
| + | |||
| + | |||
| + | === 3. Le problème du mariage === | ||
| + | |||
| + | Résoudre le problème du mariage avec les données suivantes : | ||
| + | <code python> | ||
| + | CLEOPATRE = " | ||
| + | IPHIGENIE = " | ||
| + | JULIETTE = " | ||
| + | FANNY = " | ||
| + | CHIMENE = " | ||
| + | |||
| + | ACHILLE = " | ||
| + | CESAR = " | ||
| + | RODRIGUE = " | ||
| + | ROMEO = " | ||
| + | MARIUS = " | ||
| + | |||
| + | LES_COUPLES = [(CLEOPATRE, | ||
| + | | ||
| + | | ||
| + | </ | ||
| + | |||
| + | <note important> | ||
| + | La difficulté (puisque l' | ||
| + | </ | ||
| + | |||
| + | === 4. La bataille de la Marne === | ||
| + | |||
| + | Résoudre le problème de "la bataille de la Marne", | ||
| + | * Au temps 0, on a autant de taxis que nécessaire dans la ville 14 (" | ||
| + | * Au temps 50, il faut qu'il y en ait le plus possible dans la ville 0 ("La Marne" | ||
| + | * Chaque ville (intermédiaire) a 10 places de parking (Paris en a autant que nécessaire). | ||
| + | * Les routes sont données dans le tableau suivant : | ||
| + | |||
| + | |||
| + | <code python> | ||
| + | LES_ROUTES = [{' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | </ | ||
| + | |||
| + | <note important> | ||
| + | Les routes sont à double sens (il ne faut pas se fier aux appellations " | ||
| + | </ | ||
| + | |||
| + | <note important> | ||
| + | La difficulté est, là encore, la construction du graphe. | ||
| + | </ | ||
| + | |||
| + | |||
| + | On pourra commencer par une instance plus petite, par exemple en ne considérant que les villes jusqu' | ||
| + | |||
| + | <code python> | ||
| + | LES_ROUTES = [{' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | {' | ||
| + | </ | ||
| + | |||
| + | voire même plus petit. | ||