Académique Documents
Professionnel Documents
Culture Documents
Algorithmes gloutons
Travaux dirigés et pratiques n˚4
Algorithmes gloutons
Exercice 1 : Le coût de la non-panne sèche
Le Professeur Adel conduit une voiture entre Tunis et Agadir (Maroc)
sur l'autoroute transmaghrébine. Son réservoir, quand il est plein,
contient assez d'essence pour faire n kilomètres, et son smartphone lui
donne les distances entre les stations-service sur la route.
1. Donnez une méthode efficace grâce à laquelle le Professeur Adel
pourra déterminer les stations-service où il peut s'arrêter, sachant qu'il
souhaite faire le moins d'arrêts possible.
Voici un pseudo-code qui pourrait être utilisé pour résoudre ce problème :
1. Définir une liste vide stations pour stocker les stations-service où le Professeur
Adel peut s'arrêter.
2. Définir une variable distance_parcourue qui représente la distance parcourue
par le Professeur Adel depuis le début de son voyage.
3. Récupérer les distances entre les stations-service sur la route depuis le
smartphone du Professeur Adel.
4. Pour chaque distance entre les stations-service : a. Ajouter cette distance à la
distance parcourue. b. Si la distance parcourue est supérieure ou égale à la
distance maximale que peut parcourir la voiture du Professeur Adel avec un
réservoir plein, ajouter la station-service actuelle à la liste stations et réinitialiser
la distance parcourue à zéro.
5. Afficher la liste stations des stations-service où le Professeur Adel peut s'arrêter.
#include <stdio.h>
return 0;
}
Notez que la fonction get_distances_from_smartphone doit être implémentée de manière
à récupérer les distances entre les stations-service depuis le smartphone du Professeur Adel.
Cette fonction doit renvoyer le nombre de distances récupérées et stocker ces distances dans le
tableau distances.
Cette stratégie est optimale, car elle permet de minimiser le nombre d'arrêts nécessaires
en s'assurant que la voiture du Professeur Adel ne tombe jamais en panne d'essence. En
effet, en s'arrêtant dès que la distance parcourue atteint la distance maximale, le
Professeur Adel peut s'assurer qu'il a toujours assez d'essence pour continuer son
voyage jusqu'à la prochaine station-service.
#include <iostream>
#include <algorithm>
int main() {
cin >> n;
for (int i = 0; i < n; i++) {
cin >> courses[i].start >> courses[i].end;
}
// Afficher le résultat
for (int i = 0; i < n; i++) {
cout << "Cours " << i + 1 << ": Salle " << courses[i].room + 1 << endl;
}
return 0;
}
Ce code commence par lire le nombre de cours et les informations sur chacun d'eux (heure de
début et heure de fin). Il trie ensuite les cours par ordre croissant d'heure de début, ce qui
permet de parcourir les cours dans l'ordre chronologique. Pour chaque cours, il parcourt toutes
les salles disponibles et attribue la première salle qui n'est pas occupée pendant ce cours à ce
dernier. Enfin, il affiche le résultat de l'attribution.
Fi(T1) = 3
Fi(T4) = 3 + 4 = 7
Fi(T2) = 3 + 4 + 5 = 12
Fi(T3) = 3 + 4 + 5 + 7 = 19
Pour la réalisation (T4, T1, T3, T2), la pénalité est donnée par :
Fi(T4) = 4
Fi(T1) = 4 + 3 = 7
Fi(T3) = 4 + 3 + 7 = 14
Fi(T2) = 4 + 3 + 7 + 4 = 18
La réalisation (T1, T4, T2 , T3) est donc la meilleure car elle a une pénalité inférieure à
celle de la réalisation (T4, T1, T3, T2).
Si nous exécutons en premier la tâche Ti, la pénalité associée à cette tâche sera pi * Fi = 10 * 4 = 40.
La pénalité associée à la tâche Tj sera pj * Fi = 15 * (4 + 3) = 75. La pénalité totale sera donc de 40 +
75 = 115.
Si nous exécutons en premier la tâche Tj, la pénalité associée à cette tâche sera pj * Fi = 15 * 3 = 45.
La pénalité associée à la tâche Ti sera pi * Fi = 10 * (3 + 4) = 70. La pénalité totale sera donc de 45 +
70 = 115.
Dans les deux cas, la pénalité totale est la même. Cependant, en exécutant en premier la tâche Ti,
nous avons minimisé la pénalité associée à cette tâche, ce qui est préférable pour minimiser la
pénalité totale.
3. En déduire un algorithme.
Ce pseudo-code commence par lire les informations sur chaque tâche et les trie par
ordre croissant de priorité (pi/di). Il initialise ensuite une liste de tâches ordonnancées et
ajoute chaque tâche à cette liste dans l'ordre de priorité. Enfin, il calcule la pénalité
totale de l'ordonnancement en utilisant la formule pi * Fi et affiche le résultat.
#include <iostream>
#include <algorithm>
int main() {
cin >> n;
for (int i = 0; i < n; i++) {
cin >> tasks[i].duration >> tasks[i].priority;
tasks[i].value = (double) tasks[i].priority / tasks[i].duration;
}
// Afficher le résultat
cout << "Pénalité totale : " << penalty << endl