Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions MyIA.AI.Notebooks/Sudoku/Sudoku-01-Backtracking-Csharp.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,27 @@
"\n"
]
},
{
"cell_type": "markdown",
"id": "9ef4239f",
"metadata": {},
"source": [
"### Lecture : `122` -> `490304` -> `12625368` appels, pour le même code\n",
"\n",
"Les trois tests lancent exactement le même `BacktrackingDotNetSolver` ; seule\n",
"la densité d'indices change (`45` indices pour la grille facile, `22` pour la\n",
"moyenne, `17` pour la difficile). Le compteur d'appels rend la combinatoire\n",
"visible : passer de `36` à `64` cases vides multiplie l'exploration par cent\n",
"mille. L'algorithme n'a pas ralenti ; l'espace de recherche a grandi, et le\n",
"backtracking le parcourt sans autre guide que l'ordre fixe des cellules.\n",
"\n",
"C'est la motivation de toute la suite : l'exercice guidé MRV ci-dessous, puis\n",
"les notebooks 06 et 09, ne changent pas la correction de la recherche — ils\n",
"changent l'ordre d'exploration pour couper les branches stériles plus tôt. Le\n",
"temps total (`0,9` ms / `285` ms / `8,7` s) reste proportionnel aux appels :\n",
"chaque appel coûte le même ordre de grandeur, c'est leur nombre qui explose."
]
},
{
"cell_type": "markdown",
"id": "4261aa01",
Expand Down
162 changes: 162 additions & 0 deletions MyIA.AI.Notebooks/Sudoku/Sudoku-03-Genetic-Csharp.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,24 @@
"#r \"nuget: GeneticSharp\""
]
},
{
"cell_type": "markdown",
"id": "7dbacb83",
"metadata": {},
"source": [
"### Lecture : `#r nuget: GeneticSharp` — le framework évolutionnaire, pas une réimplémentation\n",
"\n",
"La première cellule de code installe GeneticSharp par NuGet : sélection,\n",
"crossover, mutation et gestion de population viennent d'une bibliothèque .NET\n",
"dédiée, et tout ce que ce notebook écrit lui-même tourne autour — chromosome,\n",
"fitness, tests. C'est la position inverse du jumeau Python, qui code le GA à la\n",
"main sur numpy : le même enseignement algorithmique, deux niveaux\n",
"d'abstraction. Le choix rend visible ce qu'un framework apporte et ce qu'il ne\n",
"remplace pas : la qualité de la recherche dépend presque entièrement des deux\n",
"classes définies ici-même, le chromosome (comment encoder une grille) et la\n",
"fitness (comment la noter)."
]
},
{
"cell_type": "markdown",
"id": "218e1883",
Expand Down Expand Up @@ -239,6 +257,22 @@
"#!import Sudoku-00-Environment-Csharp.ipynb"
]
},
{
"cell_type": "markdown",
"id": "7a941af5",
"metadata": {},
"source": [
"### Lecture : une instance partagée par toute la série\n",
"\n",
"L'import de `Sudoku-00-Environment` charge les grilles et helpers communs : le\n",
"puzzle facile testé plus bas est exactement celui des notebooks 01 et 09\n",
"(reconnaissable à sa première ligne `9 · 2 | · 5 | 4 · 3`). Cette convention a\n",
"une conséquence directe sur la lecture des résultats : quand le solveur\n",
"génétique mettra douze secondes là où le backtracking de Sudoku-01 mettait\n",
"`0,9` ms, la différence ne viendra ni des données ni du langage — uniquement\n",
"de l'algorithme. Toute la série compare des méthodes sur un terrain fixe."
]
},
{
"cell_type": "markdown",
"id": "47ce5ce8",
Expand Down Expand Up @@ -308,6 +342,23 @@
"Console.WriteLine(\"Interface ISudokuChromosome definie (chromosome Sudoku avec TargetSudoku + GetSolution)\");"
]
},
{
"cell_type": "markdown",
"id": "2c165d34",
"metadata": {},
"source": [
"### Lecture : le contrat du chromosome\n",
"\n",
"L'interface pose deux membres : `TargetSudoku` (la grille à résoudre) et\n",
"`GetSolution()` (reconstruire une grille complète depuis les gènes). Tout l'art\n",
"du chromosome tient dans cette seconde opération : les gènes forment un espace\n",
"de recherche arbitraire — 81 valeurs libres, 9 permutations, autre chose — et\n",
"`GetSolution` traduit cet espace en grille candidate. La fitness jugera la\n",
"candidate, jamais les gènes directement. Cette séparation est ce qui permettra\n",
"en fin de notebook de changer complètement d'espace de recherche sans toucher\n",
"ni au solveur ni à la fitness."
]
},
{
"cell_type": "markdown",
"id": "dc758960",
Expand Down Expand Up @@ -423,6 +474,24 @@
"Console.WriteLine(\"Classe SudokuFitness definie (evaluation par nombre d'erreurs negatif)\");"
]
},
{
"cell_type": "markdown",
"id": "8ae3278f",
"metadata": {},
"source": [
"### Lecture : la fitness vaut `-erreurs` — un paysage sans pente\n",
"\n",
"`SudokuFitness` évalue un chromosome par l'opposé de son nombre d'erreurs :\n",
"grille parfaite = 0 conflit = fitness 0, et tout est négatif en dessous. Ce\n",
"choix simple façonne toute la recherche : il n'existe aucune gradation d'«\n",
"presque bon ». Une grille à 3 conflits et une à 30 conflits disent toutes deux\n",
"« négatif » sans indiquer dans quelle direction améliorer. C'est un paysage en\n",
"marches d'escalier, sans gradient — exactement le terrain où l'exploration\n",
"stochastique (mutation, crossover) a du sens et où un simple hill-climber\n",
"piétine. L'exercice de fitness pondérée ci-dessus propose précisément de\n",
"raffiner cette mesure."
]
},
{
"cell_type": "markdown",
"id": "7838974a",
Expand Down Expand Up @@ -567,6 +636,24 @@
"Console.WriteLine(\"Classe SudokuGeneticSolver definie (solver avec population dynamique et parallelisme TPL)\");"
]
},
{
"cell_type": "markdown",
"id": "2821b9f6",
"metadata": {},
"source": [
"### Lecture : population dynamique et parallélisme TPL\n",
"\n",
"Le solver annonce deux mécanismes au-delà du cycle GA standard. La population\n",
"dynamique ajuste la taille de la population en cours de route : élargir quand\n",
"la recherche stagne (plus de diversité génétique), resserrer quand elle\n",
"progresse (concentrer l'effort sur les meilleures lignées). Le parallélisme TPL\n",
"exploite le fait que l'évaluation d'un chromosome est indépendante de celle de\n",
"ses congénères : toute une population s'évalue simultanément sur les cœurs\n",
"disponibles. Notez ce que cela suppose : la fitness est une fonction pure du\n",
"chromosome, sans état partagé — c'est cette propriété qui rend le parallélisme\n",
"trivial."
]
},
{
"cell_type": "markdown",
"id": "a21f9896",
Expand Down Expand Up @@ -704,6 +791,24 @@
"Console.WriteLine(\"Classe SudokuCellsChromosome definie (81 genes, un par cellule)\");"
]
},
{
"cell_type": "markdown",
"id": "379be542",
"metadata": {},
"source": [
"### Lecture : première représentation — un gène par cellule\n",
"\n",
"`SudokuCellsChromosome` encode la grille de la manière la plus directe qui\n",
"soit : 81 gènes, un par cellule, chacun libre de valoir 1 à 9. La force de\n",
"cette représentation est sa généralité — elle peut exprimer n'importe quelle\n",
"grille ; sa faiblesse est qu'elle n'en exprime aucune contrainte : rien ne\n",
"distingue génétiquement une ligne valide d'une ligne en doublon. Toute la\n",
"pression vers la validité repose sur la fitness. Le test suivant montre ce que\n",
"cela coûte : l'algorithme finit par trouver la solution, mais il doit\n",
"apprendre par sélection ce que d'autres représentations obtiennent par\n",
"construction."
]
},
{
"cell_type": "markdown",
"id": "54f71b49",
Expand Down Expand Up @@ -812,6 +917,24 @@
"SudokuHelper.SolveSudoku(easySudoku, solver);"
]
},
{
"cell_type": "markdown",
"id": "6844df54",
"metadata": {},
"source": [
"### Lecture : résolu — mais à quel prix\n",
"\n",
"`Nombre d'erreurs restantes: 0` : le chromosome par cellules finit par\n",
"produire la grille exacte. Le nombre à côté est tout aussi instructif :\n",
"`12727` ms. Rappelez-vous le terrain — c'est la grille facile, la même que le\n",
"backtracking de Sudoku-01 résolvait en `0,9` ms, quatorze mille fois plus\n",
"vite. Le GA n'est pas « plus lent » dans l'absolu : il paie ici le prix de sa\n",
"représentation permissive. La population part de grilles aléatoires et doit\n",
"éliminer des millions de grilles invalides avant d'approcher la région valide.\n",
"La question devient : peut-on coder la validité dans les gènes eux-mêmes ?\n",
"C'est l'objet de la seconde représentation."
]
},
{
"cell_type": "markdown",
"id": "77671ef0",
Expand Down Expand Up @@ -1150,6 +1273,24 @@
"Console.WriteLine(\"Classe SudokuPermutationsChromosome definie (9 genes, permutations de lignes validees)\");"
]
},
{
"cell_type": "markdown",
"id": "48d96f82",
"metadata": {},
"source": [
"### Lecture : seconde représentation — neuf gènes de permutation\n",
"\n",
"Le changement est radical : plus 81 gènes libres, mais 9 gènes — un par ligne\n",
"— où chaque gène encode une permutation des chiffres 1 à 9. Conséquence\n",
"immédiate : chaque ligne d'une grille candidate contient exactement une fois\n",
"chaque chiffre, par construction. Une famille entière de conflits — les\n",
"doublons de ligne — ne peut plus jamais exister, quel que soit le crossover ou\n",
"la mutation : la recherche ne vit plus que dans l'espace des grilles à lignes\n",
"valides. C'est la leçon structurelle du notebook : la représentation est\n",
"elle-même un algorithme — réduire l'espace de recherche vaut mieux que chercher\n",
"mieux dans un espace trop grand."
]
},
{
"cell_type": "markdown",
"id": "5347dc92",
Expand Down Expand Up @@ -1303,6 +1444,27 @@
"SudokuHelper.SolveSudoku(mediumSudoku, solver);"
]
},
{
"cell_type": "markdown",
"id": "d8c2dc3d",
"metadata": {},
"source": [
"### Lecture : `186` ms contre `12727` — puis `6` erreurs : la représentation choisit son terrain\n",
"\n",
"Sur la grille facile, la comparaison est sans appel : même solveur, même\n",
"fitness, seule la représentation change — `186` ms contre `12727`, un facteur\n",
"68, pour la même solution exacte. Mais la seconde moitié de la sortie est la\n",
"contrepartie : sur la grille moyenne (`22` indices), le même chromosome par\n",
"permutations bute à `6` erreurs restantes après `42` secondes de sélection.\n",
"Les lignes sont valides par construction ; les contraintes de colonne et de\n",
"bloc, elles, n'ont aucun encodage génétique — permuter une ligne peut les\n",
"satisfaire ou les violer sans que le gène en porte la trace, et les\n",
"croisements de permutations défont facilement des alignements acquis. La\n",
"leçon est complète : une représentation puissante sur un terrain peut être\n",
"pauvre sur un autre ; elle choisit quelles contraintes l'algorithme doit\n",
"encore découvrir."
]
},
{
"cell_type": "markdown",
"id": "6f705b5b",
Expand Down
Loading
Loading