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 | ||
restricted:alg-1:tp4 [2015/10/31 10:17] – fbrucker | restricted:alg-1:tp4 [2016/01/22 11:25] (Version actuelle) – fbrucker | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
+ | ====== TP4 ====== | ||
+ | |||
+ | Le but de ce TP est de résoudre des problèmes d' | ||
+ | |||
+ | |||
+ | Ici, on suppose que l'on a de l'aide pour s' | ||
+ | |||
+ | {{restricted: | ||
+ | |||
+ | |||
+ | < | ||
+ | Le fait de tester toutes vos créations n'est plus explicitement demandé car cela doit **toujours** être fait. | ||
+ | </ | ||
+ | ===== Structure de graphe ===== | ||
+ | |||
+ | Lors du [[restricted: | ||
+ | |||
+ | ==== Graphe d' | ||
+ | |||
+ | Avec cette structure, on commence par initialiser le graphe et ses sommets : | ||
+ | |||
+ | <code python> | ||
+ | graphe_habillage = dict() | ||
+ | |||
+ | habillage = dict() | ||
+ | |||
+ | habillage[" | ||
+ | habillage[" | ||
+ | habillage[" | ||
+ | habillage[" | ||
+ | habillage[" | ||
+ | habillage[" | ||
+ | habillage[" | ||
+ | habillage[" | ||
+ | habillage[" | ||
+ | </ | ||
+ | |||
+ | La variable **habillage** (un dictionnaire) contient 9 clés (les sommets du graphes), associés à un ensemble vide (les voisins). | ||
+ | |||
+ | On peut maintenant remplir le graphe avec les voisins. On utilise la méthode **add** des ensemble qui permet d' | ||
+ | |||
+ | <code python> | ||
+ | habillage[" | ||
+ | habillage[" | ||
+ | |||
+ | habillage[" | ||
+ | |||
+ | habillage[" | ||
+ | |||
+ | habillage[" | ||
+ | habillage[" | ||
+ | |||
+ | habillage[" | ||
+ | habillage[" | ||
+ | </ | ||
+ | |||
+ | Le graphe est maintenant complet. | ||
+ | |||
+ | On peut alors afficher ses sommets : | ||
+ | <code python> | ||
+ | for sommet in habillage: | ||
+ | print(sommet) | ||
+ | </ | ||
+ | |||
+ | Connaître les voisins d'un sommets : | ||
+ | <code python> | ||
+ | print(habillage[" | ||
+ | </ | ||
+ | |||
+ | Connaître tout le graphe: | ||
+ | <code python> | ||
+ | for sommet in habillage: | ||
+ | print(" | ||
+ | </ | ||
+ | |||
+ | ==== Ajout du départ et de la fin ==== | ||
+ | |||
+ | En ordonnancement il n' | ||
+ | |||
+ | On va automatiser l' | ||
+ | - créez deux fonctions : | ||
+ | * une fonction qui à partir d'un graphe rend l' | ||
+ | * une fonction qui à partir d'un graphe rend l' | ||
+ | - mettez à jour le graphe : | ||
+ | - ajoutez deux sommets " | ||
+ | - les voisins de départ sont les sommets rendus par la première fonction, | ||
+ | - ajoutez " | ||
+ | |||
+ | À la fin le code suivant : | ||
+ | <code python> | ||
+ | for sommet in habillage: | ||
+ | print(" | ||
+ | </ | ||
+ | Doit rendre quelque chose du genre: | ||
+ | < | ||
+ | le sommet | ||
+ | le sommet | ||
+ | le sommet | ||
+ | le sommet | ||
+ | le sommet | ||
+ | le sommet | ||
+ | le sommet | ||
+ | le sommet | ||
+ | le sommet | ||
+ | le sommet | ||
+ | le sommet | ||
+ | </ | ||
+ | |||
+ | |||
+ | ===== Chemin critique ===== | ||
+ | |||
+ | Un chemin critique est un chemin le plus long entre les sommets " | ||
+ | |||
+ | On utilisera le [[restricted: | ||
+ | |||
+ | <code python> | ||
+ | def tri_topologique(sommet_depart, | ||
+ | |||
+ | def tri_topologique_recursif(s, | ||
+ | sommets_marqués.add(s) | ||
+ | for voisin in graphe[s]: | ||
+ | if voisin not in sommets_marqués: | ||
+ | tri_topologique_recursif(voisin, | ||
+ | sommets_ordonnes_inverse.append(s) | ||
+ | |||
+ | liste_tri_topologique = [] | ||
+ | tri_topologique_recursif(sommet_depart, | ||
+ | liste_tri_topologique.reverse() | ||
+ | |||
+ | return liste_tri_topologique | ||
+ | </ | ||
+ | |||
+ | |||
+ | On vous demande d' | ||
+ | |||
+ | < | ||
+ | # initialisation | ||
+ | pere = dict() | ||
+ | longueur_chemin = dict() | ||
+ | pour chaque sommet x du graphe g: | ||
+ | pere[x] = None # pas de pere pour l' | ||
+ | longueur_chemin[x] = 0 # chemin plus long entre départ et x vaut 0 pour l' | ||
+ | |||
+ | # parcours | ||
+ | pour chaque x de tri: | ||
+ | pour chaque y de g[x]: | ||
+ | si x == " | ||
+ | durée = 0 # durée de la tâche " | ||
+ | sinon: | ||
+ | durée = 1 # durée de la tâche x | ||
+ | | ||
+ | si longueur_chemin[y] ≤ longueur_chemin[x] + durée: | ||
+ | longueur_chemin[y] = longueur_chemin[x] + durée | ||
+ | pere[y] = x | ||
+ | |||
+ | # chemin critique | ||
+ | chemin_critique = [] | ||
+ | tache_courante = " | ||
+ | ajoute " | ||
+ | |||
+ | tant que tache_courante != " | ||
+ | tache_courante = pere[tache_courante] | ||
+ | ajouter tache_courante au debut de chemin critique | ||
+ | |||
+ | rendre chemin_critique | ||
+ | </ | ||
+ | |||
+ | Il n' | ||
+ | - ' | ||
+ | - ' | ||
+ | - ' | ||
+ | - ' | ||
+ | - ' | ||
+ | - ' | ||
+ | |||
+ | |||
+ | ===== Début et fin de tâches ===== | ||
+ | |||
+ | Le chemin critique conditionne le temps mis pour exécuter le projet. Chaque tâche de ce chemin doit donc commencer exactement après la tache précédente sinon le projet prendra du retard. | ||
+ | |||
+ | Les autres tâches, en revanche, peuvent commencer une fois que tous ses prédécesseurs ont ́été terminés, mais doivent obligatoirement finir avant le début des tâches qui lui succèdent dans le chemin vers la fin du projet. On renseigne alors pour chaque tâche une date de début au plus tôt et une date de début au plus tard (ces dates sont identiques pour les tâches du chemin critique). | ||
+ | |||
+ | < | ||
+ | On ne prendra pas en compte les marges partagées. En effet commencer une tâche plus tard va impacter tout ses successeurs. | ||
+ | </ | ||
+ | |||
+ | ==== date au plus tôt ==== | ||
+ | |||
+ | Donné par la valeur de **longueur_chemin** dans le calcul du chemin critique. | ||
+ | |||
+ | Donnez ces dates pour toutes les tâches. | ||
+ | |||
+ | ==== date au plus tard ==== | ||
+ | |||
+ | Elle est déterminée par le chemin le plus long entre ses successeurs et la fin du projet moins le temps pour effectuer cette tâche. On peut calculer cette valeur pour toutes les tâches en parcourant les éléments du tri topologique en partant de la fin. La date de fin d’une tâche est alors le minimum de la date de fin au plus tard de ses successeurs moins la durée de la tâche (ici toujours 1 sauf pour le sommet ”départ” qui est de durée 0). On connaît la date au plus tard du dernier | ||
+ | |||
+ | Implémentez l' | ||