LGT Saint-Exupéry, Mantes-la-Jolie
Activité Terminale NSI – Programmation dynamique – Exemples sous Python 1/2
Objectifs pédagogiques :
✓ Utiliser la programmation dynamique pour écrire un algorithme.
✓ Découvrir l’intérêt de la programmation dynamique pour les recherches d’alignement de séquences.
✓ Comparer un algorithme de force brute, un algorithme glouton et un algorithme en programmation dynamique sur rendu de monnaie (à partir des connaissances de la classe de 1ère NSI).
✓ Montrer les conséquences sur le coût en mémoire des algorithmes de programmation dynamique.
Richard Bellman est un mathématicien américain, travaillant principalement dans la branche des mathématiques appliquées. Il est l'inventeur de la programmation dynamique, qui résolut à son époque de façon inespérée l'optimisation des sommes de fonctions monotones croissantes sous contraintes.
Activité 1 – L’alignement de séquences
1. Regarder la capsule vidéo sur la programmation dynamique (épisode #1 sur les alignements de séquences) sur le site nsi4noobs.fr
2. Donner le principe de base de la programmation dynamique.
3. Dans quel domaine scientifique l’utilisation de la programmation dynamique a connu un grand essor ?
4. Quel type de fonction utilise régulièrement la programmation dynamique ? 5. Détailler le principe de la recherche de l’alignement de séquences.
6. Reprendre l’algorithme de calcul de la distance de Levenshtein et le tester avec les séquences
« information » et « informatique ».
7. Relancer le calcul en modifiant la matrice de Levenshtein en prenant un poids de 4 pour un bon alignement et -2 pour une insertion, suppression, modification.
Activité 2 – Le rendu de monnaie
1. Regarder la capsule vidéo sur la programmation dynamique (épisode #2 sur le rendu de monnaie) sur le site nsi4noobs.fr
2. Écrire l’algorithme en Python du rendue de monnaie force brute (et fonction récursive).
3. Dessiner le début de l’arbre des possibilités de rendue de monnaie pour 76 cts. Montrer sur cet arbre qu’il y a des redondances.
4. Écrire l’algorithme en Python du rendue de monnaie en programmation dynamique.
5. A l’aide de la fonction time() de la bibliothèque time de Python, évaluer le temps nécessaire pour votre ordinateur pour calculer le nombre minimal de pièces à rendre pour la somme de 76 cts à l’aide des deux algorithmes (questions 2 et 4)
6. Même chose avec 177 cts. Commenter.
Algorithmique
Programmation dynamique
Exemples sous Python
LGT Saint-Exupéry, Mantes-la-Jolie
Activité Terminale NSI – Programmation dynamique – Exemples sous Python 2/2
Activité 3 – Application de la programmation dynamique à la suite de Fibonacci
La suite d’entiers 0, 1, 1, 2, 3, 5, 8, 13, 21, . . . où chaque terme s’obtient en additionnant les deux précédents porte le nom de suite de Fibonacci, en hommage à Leonardo Fibonacci mathématicien italien du XIIIème siècle qui l’avait utilisée pour modéliser l’évolution d’une population de lapins.
En langage moderne mathématique, cette suite que l’on notera (Fn)n est définie par ses deux premiers termes F0 = 0, F1 = 1 et la relation de récurrence :
n ℕ, Fn+2 = Fn+1 + Fn.
1. Écrire l’algorithme en Python à l’aide d’une fonction récursive simple fibonacci_rec(n) permettant le calcul d’un terme de la suite de Fibonacci (n étant le terme de la suite de Fibonacci à calculer)
2. Écrire l’algorithme en Python à l’aide d’une fonction récursive en programmation dynamique fibonacci(n, fibo_memo) permettant le calcul d’un terme de la suite de Fibonacci (n étant le terme de la suite de Fibonacci à calculer et fibo_memo le tableau de mémorisation des termes déjà calculés) 3. Évaluer le temps mis par vos deux algorithmes pour calculer F40. Commenter.
4. Quel est le principal avantage de la programmation dynamique ?
5. Quel inconvénient peut survenir avec l’utilisation de la programmation dynamique ?
6. Évaluer le coût de stockage mémoire de votre algorithme de calcul de la suite de Fibonacci pour le terme 50 sachant que F50 = 12 586 269 025
On pourra considérer que Python utilise une allocation mémoire moyenne pour ces différents types comme suit (données très approximatives car Python adapte la taille d’allocation mémoire nécessaire à chaque donnée) :
Type Bornes Allocation mémoire
Entier court De – 2 147 483 648 à + 2 147 483 647 4 octets (32 bits) Entier long De – 1,84446744...x1019 à +1,84446744...x1019 8 octets (64 bits) Flottant (réel) De 10-308 et 10308 (en positif ou négatif) 8 octets (64 bits)
NB : une liste contenant des entiers courts nécessite en général le double d’allocation mémoire de la somme des éléments qui la constitue (adressage des données dans la liste)
Avant de passer à l’écriture d’un programme à l’aide de la programmation dynamique, vous devez :
✓ Bien souvent réfléchir à la meilleure structure à utiliser et en particulier la programmation de fonctions récursives.
✓
Évaluer le coût mémoire de la mémorisation des différentes étapesPour aller plus loin sur la programmation dynamique :
✓ https://fr.wikipedia.org/wiki/Distance_de_Levenshtein
✓ https://fr.wikipedia.org/wiki/Alignement_de_s%C3%A9quences
✓ https://fr.wikipedia.org/wiki/Programmation_dynamique
Quelques rappels sur les fonctions et particulièrement les fonctions récursives : http://nsi4noobs.fr/Cours-et-activites-sur-les-fonctions Sur le rendu de monnaie :
✓ http://nsi4noobs.fr/Algorithmes-gloutons
✓ https://fr.wikipedia.org/wiki/Probl%C3%A8me_du_rendu_de_monnaie