From 348877eb6cad2d422f391c7f7eddbc68a96426c0 Mon Sep 17 00:00:00 2001 From: Florian Mathieu Date: Fri, 11 Sep 2026 10:41:55 +0200 Subject: [PATCH] =?UTF-8?q?corrig=C3=A9s=20du=20mastermind=20hors=20public?= =?UTF-8?q?ation,=20liens=20vers=20les=20fichiers=20utiles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Projets/README.md | 2 +- Projets/mastermind/README.md | 14 +- Projets/src/{algo_gen.py => _algo_gen.py} | 2 +- .../src/{combinaison.py => _combinaison.py} | 0 Projets/src/{problem_1.py => _problem_1.py} | 0 Projets/src/{problem_2.py => _problem_2.py} | 0 Projets/src/{problem_4.py => _problem_4.py} | 0 .../src/{problem_sup.py => _problem_sup.py} | 168 +++++++++--------- Projets/src/test.py | 30 ++-- 9 files changed, 108 insertions(+), 108 deletions(-) rename Projets/src/{algo_gen.py => _algo_gen.py} (99%) rename Projets/src/{combinaison.py => _combinaison.py} (100%) rename Projets/src/{problem_1.py => _problem_1.py} (100%) rename Projets/src/{problem_2.py => _problem_2.py} (100%) rename Projets/src/{problem_4.py => _problem_4.py} (100%) rename Projets/src/{problem_sup.py => _problem_sup.py} (95%) diff --git a/Projets/README.md b/Projets/README.md index 997e4ca..660ac5b 100644 --- a/Projets/README.md +++ b/Projets/README.md @@ -23,7 +23,7 @@ Chaque projet est découpé en phases dans son fichier `JALONS.md`, sur une **pr | [Le Jeu de la Vie](jeu_de_la_vie/) | L'automate cellulaire de Conway : quatre règles, et des structures qui émergent | Grilles 2D, fonctions pures, POO | non | | [Labyrinthe](labyrinthe/) | Générer un labyrinthe parfait, puis le résoudre automatiquement | Graphes, arbres couvrants, DFS et BFS, récursivité | oui, `src/maze.py` | | [Wa-Tor](wator/) | Simuler un monde torique où des requins chassent des thons | Grilles 2D, simulation, POO | non | -| [Mastermind et algorithmes génétiques](mastermind/) | Faire évoluer une population de combinaisons jusqu'à trouver le code secret | POO, paradigme fonctionnel, optimisation | oui, `src/algo_gen.py` et `src/combinaison.py` | +| [Mastermind et algorithmes génétiques](mastermind/) | Faire évoluer une population de combinaisons jusqu'à trouver le code secret | POO, paradigme fonctionnel, optimisation | oui, les deux classes abstraites de `src/` | Le Jeu de la Vie et le Labyrinthe sont les deux plus accessibles pour démarrer. Le Labyrinthe est celui qui recoupe le plus directement le programme de Terminale, entre le chapitre Graphes et le chapitre Récursivité. diff --git a/Projets/mastermind/README.md b/Projets/mastermind/README.md index d0204b3..1630c48 100644 --- a/Projets/mastermind/README.md +++ b/Projets/mastermind/README.md @@ -8,10 +8,9 @@ Le **Mastermind** est un jeu de déduction : un joueur choisit une combinaison s Plutôt que de coder une IA par force brute, ce projet applique un **algorithme génétique** : on fait évoluer une population de combinaisons candidates en s'inspirant de la sélection naturelle (tournoi, croisement, mutation) jusqu'à trouver la solution. -Une base de code complète est disponible dans `../src/` : -- `algo_gen.py` - framework de l'algorithme génétique -- `combinaison.py` - représentation d'un individu (une combinaison) -- `src_mastermind_fiche.md` - fiche TP détaillée avec toutes les consignes +Vous ne partez pas de rien : deux classes abstraites vous sont fournies, `Individual_Interface` +et `Problem_Interface`. Vous en héritez, et vous écrivez les méthodes qu'elles laissent vides. +La fiche de TP et l'activité guidée vous mènent pas à pas. ## Compétences mobilisées @@ -42,9 +41,10 @@ Une base de code complète est disponible dans `../src/` : ## Ressources -- `../src/src_mastermind_fiche.md` - fiche TP complète avec toutes les consignes -- `../src/algo_gen.py` - squelette du framework générique -- `../src/combinaison.py` - classe individu à compléter +- [Fiche de TP](https://florianmathieu.prof/hub-docs/nsi/terminale/Projets/src/src_mastermind_fiche/) - toutes les consignes, dans l'ordre +- [Activité guidée](https://florianmathieu.prof/hub-docs/nsi/terminale/Projets/src/Activit%C3%A9/) - le pas à pas complet, avec les explications +- [`individual_interface.py`](https://florianmathieu.prof/hub-docs/nsi/terminale/Projets/src/individual_interface/individual_interface.py) - classe abstraite d'un individu, à hériter +- [`problem_interface.py`](https://florianmathieu.prof/hub-docs/nsi/terminale/Projets/src/problem_interface/problem_interface.py) - classe abstraite d'un problème, à hériter - [Algorithme génétique - Wikipedia](https://fr.wikipedia.org/wiki/Algorithme_génétique) - [Mastermind - Wikipedia](https://fr.wikipedia.org/wiki/Mastermind) diff --git a/Projets/src/algo_gen.py b/Projets/src/_algo_gen.py similarity index 99% rename from Projets/src/algo_gen.py rename to Projets/src/_algo_gen.py index 89018d9..2955ed4 100644 --- a/Projets/src/algo_gen.py +++ b/Projets/src/_algo_gen.py @@ -1,4 +1,4 @@ -from problem_sup import * +from _problem_sup import * BEST_KEPT = 5 diff --git a/Projets/src/combinaison.py b/Projets/src/_combinaison.py similarity index 100% rename from Projets/src/combinaison.py rename to Projets/src/_combinaison.py diff --git a/Projets/src/problem_1.py b/Projets/src/_problem_1.py similarity index 100% rename from Projets/src/problem_1.py rename to Projets/src/_problem_1.py diff --git a/Projets/src/problem_2.py b/Projets/src/_problem_2.py similarity index 100% rename from Projets/src/problem_2.py rename to Projets/src/_problem_2.py diff --git a/Projets/src/problem_4.py b/Projets/src/_problem_4.py similarity index 100% rename from Projets/src/problem_4.py rename to Projets/src/_problem_4.py diff --git a/Projets/src/problem_sup.py b/Projets/src/_problem_sup.py similarity index 95% rename from Projets/src/problem_sup.py rename to Projets/src/_problem_sup.py index 8cc7a22..380cc59 100644 --- a/Projets/src/problem_sup.py +++ b/Projets/src/_problem_sup.py @@ -1,84 +1,84 @@ -from problem_interface import * -from combinaison import * - -class Problem_5(Problem_Interface) : - """ - classe probleme n°5 : Combinaison Coffre-Fort - """ - - def __init__(self, calcul): - self.__size = len(calcul) - self.__combinaison = calcul - - - - def create_individual(self): - ''' - create a randomly generated indidivual for this problem - - :return: a randomly generated individual gfor this problem - :rtype: an Individual object - ''' - return Combinaison(self.__size) - - def evaluate_fitness(self, individual): - ''' - compute the fitness of individual for this problem - - :param individual: the individual to consider - :type individual: an Individual object - :return: the fitness of individual for this problem - :rtype: an Individual object - ''' - - return sum([1 if calcul[chiffre]==self.__combinaison[chiffre] else 0 for chiffre in range(len(calcul))]) - - - def sort_population(self, population): - ''' - sort population from best fitted to worst fitted individuals. - Depending on the problem, it can correspond to ascending or descending order with respect to the fitness function. - - side effect : population is modified by this method - - :param population: the list of individuals to sort - :type population: list(Individual) - ''' - population.sort(key = lambda x: x.get_score()) - - def best_individual(self, population): - ''' - return the best fitted individual from population. - Depending on the problem, it can correspond to the individual with the highest or the lowest fitness value. - - - :param population: the list of individuals to sort - :type population: list(Individual) - :return: the best fitted individual of population - :rtype: an Individual object - ''' - self.sort_population(population) - return population[len(population) -1 ] - - def tournament(self, first, second): - ''' - perform a rounament between two individuals, the winner is the most fitted one, it is returned - - - :param first: an individual - :type first: an Individual object - :param second: an individual - :type second: an Individual object - :return: the winner of the tournament - :rtype: Individual object - ''' - if first.get_score() < second.get_score(): - res = first - else: - res = second - return res - - - - - +from problem_interface import * +from _combinaison import * + +class Problem_5(Problem_Interface) : + """ + classe probleme n°5 : Combinaison Coffre-Fort + """ + + def __init__(self, calcul): + self.__size = len(calcul) + self.__combinaison = calcul + + + + def create_individual(self): + ''' + create a randomly generated indidivual for this problem + + :return: a randomly generated individual gfor this problem + :rtype: an Individual object + ''' + return Combinaison(self.__size) + + def evaluate_fitness(self, individual): + ''' + compute the fitness of individual for this problem + + :param individual: the individual to consider + :type individual: an Individual object + :return: the fitness of individual for this problem + :rtype: an Individual object + ''' + + return sum([1 if calcul[chiffre]==self.__combinaison[chiffre] else 0 for chiffre in range(len(calcul))]) + + + def sort_population(self, population): + ''' + sort population from best fitted to worst fitted individuals. + Depending on the problem, it can correspond to ascending or descending order with respect to the fitness function. + + side effect : population is modified by this method + + :param population: the list of individuals to sort + :type population: list(Individual) + ''' + population.sort(key = lambda x: x.get_score()) + + def best_individual(self, population): + ''' + return the best fitted individual from population. + Depending on the problem, it can correspond to the individual with the highest or the lowest fitness value. + + + :param population: the list of individuals to sort + :type population: list(Individual) + :return: the best fitted individual of population + :rtype: an Individual object + ''' + self.sort_population(population) + return population[len(population) -1 ] + + def tournament(self, first, second): + ''' + perform a rounament between two individuals, the winner is the most fitted one, it is returned + + + :param first: an individual + :type first: an Individual object + :param second: an individual + :type second: an Individual object + :return: the winner of the tournament + :rtype: Individual object + ''' + if first.get_score() < second.get_score(): + res = first + else: + res = second + return res + + + + + diff --git a/Projets/src/test.py b/Projets/src/test.py index 880ec47..707dc6c 100644 --- a/Projets/src/test.py +++ b/Projets/src/test.py @@ -1,16 +1,16 @@ -from algo_gen import * -from problem_4 import * - -if __name__=="__main__": - p = Problem_4([ - ['Lille', 15, 15], - ['Tourcoing', 10, 20], - ['Paris', 5, 20], - ['Alsace', 5, 30], - ['Londre', 30, 15], - ['Strasburg', 30, 30], - ['Moskou', 5, 5], - ['San Francisco', 10, 15] - ]) - a = AlgoGen(p, 1000, 0, 0.1) +from _algo_gen import * +from _problem_4 import * + +if __name__=="__main__": + p = Problem_4([ + ['Lille', 15, 15], + ['Tourcoing', 10, 20], + ['Paris', 5, 20], + ['Alsace', 5, 30], + ['Londre', 30, 15], + ['Strasburg', 30, 30], + ['Moskou', 5, 5], + ['San Francisco', 10, 15] + ]) + a = AlgoGen(p, 1000, 0, 0.1) a.solve(20) \ No newline at end of file