Cours ISC – 2014-2015 PC5 : Méthode PERT
5
def DetectCriticalTasks(self, project):
CriticalTasks = [] #On initialise une liste vide qui va contenir toutes les tâches critiques
for task in project.tasks.values():
#On boucle sur toutes les tâches du projet pour calculer la marge de manœuvre (slack)
task.slack = task.lateStart - task.earlyStart
if task.slack == 0: #si la marge de manœuvre est nulle alors il s'agit d'une tâche critique
CriticalTasks.append(task) #On ajoute la tâche à la fin de la liste
print([t.code for t in CriticalTasks]) #affichage de la liste à l'écran
Pour chaque tâche on calcule la marge de manœuvre (slack). Si elle est égale à zéro alors on ajoute la
tâche à la liste des tâches critiques.
On donne le détail du code :
Question 7 : Appliquer ces différentes méthodes sur les deux projets décrits dans les feuilles
de calcul "maison1.csv" et "maison2.csv".
Lorsque l'on applique ces méthodes sur le projet maison1 on obtient les mêmes résultats que ce qui
avait été calculé à la main. Cette constatation est rassurante sur le fait que l'algorithme proposé (et
son implémentation) est dépourvu de bogue. Il ne s'agit cependant pas d'une preuve.
L'algorithme peut alors être testé sur le projet maison2. Le diagramme PERT obtenu peut être visualisé
en pièce jointe.
Voir PERT maison 2.pdf
Une vérification manuelle des résultats rassure à nouveau sur la justesse du programme.
La date de fin de projet au plus tôt pour maison2 est 34 unités de temps.
Le chemin critique est A, B, C, D, G, H, I, L, N, O, P et Q.
Question 8 (optionnelle) : Jusqu'à présent, nous avons supposé que le modèle est correct et
en particulier qu’il ne contient pas de boucle. Compléter la méthode « DetectLoops » de la
classe « Reader » de façon à détecter la présence éventuelle de boucles dans le modèle.
Tester cette méthode en ajoutant une boucle dans l’un des deux projets.
Il y a présence d’une boucle lorsque, par exemple, une tâche B a comme prédécesseur (direct ou
indirect) une tâche A mais que cette même tâche A a également B comme prédécesseur (direct ou
indirect). Une telle situation constitue un blocage car on ne peut pas démarrer B tant que A n’est pas
terminé mais on ne peut pas commencer A tant que B n’est pas terminé.
L’objectif ici est de vérifier, dès la lecture du fichier d’entrée, que le modèle est correct de par l’absence
de boucle. La méthode « DetectLoops » a pour mission de détecter la présence d’une boucle et le cas
échéant d’afficher la boucle en question à l’écran.
On propose ici aussi un algorithme récursif pour parvenir à ce résultat. Le principe est de parcourir
pour toutes les tâches du projet, leurs prédécesseurs. Les prédécesseurs des prédécesseurs sont
parcourus de façon récursive. Si à un moment donné on retombe sur la tâche de départ alors cela
signifie qu’il y a présence d’une boucle.
Pour mettre en place cette stratégie, on utilise des marqueurs (flags) sur chacune des tâches. Pour
chaque tâche il y a trois marqueurs possibles :
« to-visit » (valeur par défaut) signifie que l’on n’a pas encore cherché à vérifier si cette tâche
fait partie ou non d’une boucle.
“visited” signifie que l’on est en train de vérifier si la tâche fait partie d’une boucle.