NUMERIQUE ET SCIENCES INFORMATIQUESNiveau : 1ère générale, enseignement de spécialité NSI
Un voleur doit amasser des objets de valeurs et les mettre dans son
sac à dos ne supporte qu'une charge de 15 kg. Quels objets devra-t-il
emporter pour partir avec la valeur la plus élevée ?
Un algorithme glouton choisit, à chaque étape, la meilleure option immédiate dans l’espoir d’obtenir une solution globale optimale.
Une première solution consiste à calculer le rapport valeur/poids
de chaque objet, puis de les amasser sans dépasser 15 kg.

On remplit le sac jusqu'à atteindre la capacité maximale.
t, qui ajoute une clé rapport et une valeur correspondant au rapport valeur/poids.tri par insertion qui prend en paramètre la liste des d'objets t et qui retourne
une liste triée par ordre décroissant du rapport valeur/poids.remplir_sac qui prend en paramètre un tableau t et entier poids_maxi.
sac qui contiendra les dictionnaires des objets que contiendra le sac.
Cette méthode nous permet d'amasser 11$ pour un poids de 11 kg. Mais est-ce pour autant meilleure la solution ? Non !, trouvez la meilleure solution.
Conclusion : un algorithme glouton est rapide mais parfois sous-optimal.
Pour résoudre ce problème avec un ordinateur, il faut explorer toutes les solutions possibles et retenir la meilleure :
Exemple de l'évolution avec un algorithme génétique.
| 10$ - 9kg |
7$ - 12kg |
1$ - 2kg |
3$ - 7kg |
2$ - 5kg |
Valeur - poids |
|---|---|---|---|---|---|
| 0 |
0 |
0 |
0 |
1 |
2$
- 5kg |
| 0 |
0 |
0 |
1 |
0 |
3$
- 7kg |
| 0 |
0 |
0 |
1 |
1 |
5$
12kg |
| 0 |
0 |
1 |
0 |
0 |
1$
- 2kg |
| ... |
|||||
| 1 |
0 |
0 |
0 |
0 |
10$
- 9kg |
| 1 |
0 |
0 |
0 |
1 |
12$ - 14kg |
| 1 |
0 |
0 |
1 |
0 |
13$ - 16kg |
On remarque que le choix des objets se fait en utilisant un code
binaire. Il y aura donc 25 = 32 possibilités.
Dans ce cas de figure, l'ordinateur ne prendra pas beaucoup de temps
à résoudre le problème parce qu'il n'y a pas beaucoup d'objets. La
complexité en en O(2n) avec n étant le nombre d'objets. Le
temps de calcul sera quand même doublé à chaque objet rajouté.
Nous allons résoudre le problème du sac à dos en utilisant une représentation binaire des solutions.
Chaque solution sera appelée un individu et sera représentée par un chromosome.
On considère la liste d'objets suivante :
objets = [
{"nom": "A", "poids": 12, "valeur": 7},
{"nom": "B", "poids": 7, "valeur": 3},
{"nom": "C", "poids": 9, "valeur": 10},
{"nom": "D", "poids": 2, "valeur": 1},
{"nom": "E", "poids": 5, "valeur": 2},
]
Un chromosome est une liste de bits dont la longueur dépend du nombre d'objets :
[1, 0, 1, 0, 1]
1 signifie que l'objet est pris
0 signifie qu'il n'est pas pris
Écrire une fonction entier_vers_chromosome(valeur, taille) qui :
valeur en paramètre et un entier correspondant au nombre d'objets taillelen(objets)Exemple :
entier_vers_chromosome(9,5) retourne [0,1,0,0,1] la fonction doit répéter 5 divisions par 2 et ajouter le reste dans un tableau : 9/2 = 4 reste 1 -> ajouter au tableau : [1] 4/2 = 2 reste 0 -> ajouter au tableau : [0,1] 2/2 = 1 reste 0 -> ajouter au tableau : [0,0,1] 1/2 = 0 reste 1 -> ajouter au tableau : [1,0,0,1] 0/2 = 0 reste 0 -> ajouter au tableau : [0,1,0,0,1] retourne le tableau
Écrire une fonction creer_individu(objets, capacite) qui retourne un la liste des dictionnaires :
{
"chromosome": [...],
"objets": [...]
"valeur": ...,
"poids": ...
}
dont le poids est inférieur ou égal à la capacité passée en paramètre.
chromosome : tableau binaireobjets : tableau des noms des objetsvaleur : somme des valeurs des objets sélectionnéspoids : somme des poidsÀ l’aide d’une boucle, générer tous les individus possibles :
for i in range(2**len(objets)):
Stocker les individus dans une liste appelée population.
On souhaite trier la population par ordre décroissant de valeur.
Vous pouvez réutiliser et adapter la fonction de tri vue précédemment.
Consigne :
while pour comparer les valeurs dans le dictionnairepopulation[j]["valeur"]Le premier individu valide sera la meilleure solution.
Traduire l'algorithme en langage python

Dans le jeu jumanji nos 4 aventuriers sont poursuivis par le chasseur Van Pelt. Il fait nuit noire et n'ont qu'une heure d'avance sur Van Pelt qui veut les éliminer.
Nos 4 aventuriers doivent traverser une passerelle en très mauvais état et ne possèdent qu'une seule torche pour s'éclairer. Vu l'état de la passerelle, seulement 2 aventuriers peuvent la traverser à la fois. L'un d'eux devra rapporter la torche pour faire traverser les suivants.
Dans quel ordre faudra-t-il faire passer nos aventuriers pour qu'ils
ne se fassent pas tuer par le chasseur et pour qu'ils puissent couper
la passerelle avant l'arrivée du chasseur.
Trois traversées sont nécessaires et il compte sur la vitesse de
calcul du microprocesseur pour résoudre le problème par le hasard.
importer la bibliothèque random personnages ← {'Ruby':5,'Smolder':10,'Franklin':20,'Shelly':25}
tps_traversee ← 100 tant que tps_traversee est supérieur à 60 depart ← la liste des clés du dictionnaire # list(personnages.keys()) mélanger la liste de départ # depart.shuffle()
arrivee ← []
tps_traversee ← 0
texte ← ""
pour i variant de 0 à 3 exclus
si le temps du premier personnage est supérieur au temps du second personnage pris dans la liste de départ
ajouter au temps de la traversée le temps du premier personnage ayant pris le départ
sinon
ajouter au temps de la traversée le temps du second personnage ayant pris le départ
fin si
ajouter à la liste d'arrivée le nom du premier personnage
ajouter à la liste d'arrivée le nom du second personnage
enlever à la liste de depart le nom du dernier personnage arrivé #indice -1
enlever à la liste de depart le nom de l'avant dernier personnage arrivé #indice -2
ajouter à la variable texte le nom des personnages ayant traversés et le temps déjà écoulé
s'il y a encore des personnages dans la liste de départ:
mélanger la liste arrivée
ajouter à tps_traverse le temps du 1er personnage de la liste arrivee
ajouter le nom du 1er personnage de la liste arrivee à la liste depart
enlever le 1er personnage de la liste arrivee
ajouter à la variable texte : le nom du personnage qui vient de traverser et le temps déjà écoulé
fin si
fin pour
fin tant que
Afficher le texte constitué et "Smolder coupe les cordes de la passerelle"
Traduire l'algorithme en langage python, puis cliquez sur enregistrer:
Exécuter plusieurs fois le programme et mettre un compteur permettant de connaître la complexité.
Pourquoi le compteur ne donne-t-il pas toujours le même résultat ?
Combien y a-t-il de solutions possibles ? lesquelles ?
Quelle est la condition d'arrêt du programme ?
Que se passe-t-il si je remplace tant que tps_traversee est supérieur à 60 par tant que
tps_traversee est supérieur à 55
Fond : Texte : Tables : Thème du langage:
Contenu
sous licence CC BY-NC-SA 3.0
Pascal Hassenforder 11/10/2020
MAJ le 31/03/2026