diff --git a/MyIA.AI.Notebooks/Search/Part4-Metaheuristics/MGS-vs-mealpy/MGS-22-MGS-vs-Mealpy.ipynb b/MyIA.AI.Notebooks/Search/Part4-Metaheuristics/MGS-vs-mealpy/MGS-22-MGS-vs-Mealpy.ipynb index 4e7e0a109e..5599d7193f 100644 --- a/MyIA.AI.Notebooks/Search/Part4-Metaheuristics/MGS-vs-mealpy/MGS-22-MGS-vs-Mealpy.ipynb +++ b/MyIA.AI.Notebooks/Search/Part4-Metaheuristics/MGS-vs-mealpy/MGS-22-MGS-vs-Mealpy.ipynb @@ -148,7 +148,7 @@ { "output_type": "stream", "name": "stdout", - "text": "MGS PSO (graine 7, témoin) : 46 conflits, 8000 évaluations, 4050 ms, cp25/50/75/100=46/46/46/46.\r\n" + "text": "MGS PSO (graine 7, témoin) : 22 conflits, 8000 évaluations, 1809 ms, cp25/50/75/100=33/26/24/22.\r\n" } ], "source": [ @@ -241,7 +241,7 @@ "2. **Le seeding précède la création de population.** `FastRandomRandomization.ResetSeed(seed)` avant `new SudokuR1Chromosome22()` — le RNG est consommé par `CreateNew()` de chaque individu initial ; re-seeder après ne fixe rien (leçon #12071). Les graines {0, 1, 7, 42} produisent des courses **reproductibles** : ré-exécuter ce notebook redonne les mêmes conflits.\n", "3. **L'échauffement est jeté, pas compté.** La première course (graine 123, 10 générations) paie la compilation JIT et l'amorçage des DLLs ; la course témoin et le bench mesurent du code chaud. Le côté mealpy aura son échauffement symétrique — sinon la comparaison des temps mesurerait l'amorçage d'un côté et le régime permanent de l'autre.\n", "\n", - "La course témoin (graine 7) donne le premier point de données. Regardez ses conflits : de l'ordre de la colonne R1/PSO de MGS-21 (médiane 45,0 à budget égal), pas de la résolution. C'est attendu — le PSO continu plafonne sur le Sudoku discret, et il plafonnera **des deux côtés** de la comparaison à venir : c'est précisément pourquoi le protocole compare à budget égal plutôt qu'à résolution." + "La première course mesurée (graine 7) donne le premier point de données : **22 conflits**, très loin de la résolution — mais **pas** parce que la grille serait vide : la grille complète comporte encore des doublons — `DecodeR1_22` remplit les cases du puzzle, et `CountConflicts22` compte les doublons, pas des cases non remplies. Le PSO continu plafonne sur le Sudoku discret, et il plafonnera **des deux côtés** de la comparaison à venir : c'est précisément pourquoi le protocole compare à budget égal plutôt qu'à résolution. Ce niveau est celui du défaut **corrigé** du composé MGS ; le profil témoin, rejoué en section 3, valait 46 conflits pour cette même graine." ] }, { @@ -264,7 +264,7 @@ { "output_type": "stream", "name": "stdout", - "text": "Pont PythonNet actif : mealpy 3.0.2 sur Python 3.13.12\r\n" + "text": "Pont PythonNet actif : mealpy 3.0.2 sur Python 3.13.15\r\n" }, { "output_type": "stream", @@ -532,7 +532,7 @@ { "output_type": "stream", "name": "stdout", - "text": "mealpy OriginalPSO (graine 7, témoin) : 26 conflits, 8050 évaluations, 3358 ms, cp25/50/75/100=35/27/26/26.\r\n" + "text": "mealpy OriginalPSO (graine 7, témoin) : 26 conflits, 8050 évaluations, 2186 ms, cp25/50/75/100=35/27/26/26.\r\n" }, { "output_type": "stream", @@ -643,42 +643,42 @@ { "output_type": "stream", "name": "stdout", - "text": "MGS 0 39 8000 1816 0,227 39/39/39/39 \r\n" + "text": "MGS 0 12 8000 1552 0,194 32/18/12/12 \r\n" }, { "output_type": "stream", "name": "stdout", - "text": "MGS 1 41 8000 1749 0,219 41/41/41/41 \r\n" + "text": "MGS 1 16 8000 1092 0,136 24/21/19/16 \r\n" }, { "output_type": "stream", "name": "stdout", - "text": "MGS 7 46 8000 1400 0,175 46/46/46/46 \r\n" + "text": "MGS 7 22 8000 1162 0,145 33/26/24/22 \r\n" }, { "output_type": "stream", "name": "stdout", - "text": "MGS 42 48 8000 1228 0,153 48/48/48/48 \r\n" + "text": "MGS 42 18 8000 1140 0,143 32/23/19/18 \r\n" }, { "output_type": "stream", "name": "stdout", - "text": "mealpy 0 30 8050 1876 0,233 41/32/31/30 \r\n" + "text": "mealpy 0 30 8050 1374 0,171 41/32/31/30 \r\n" }, { "output_type": "stream", "name": "stdout", - "text": "mealpy 1 27 8050 1600 0,199 43/35/29/27 \r\n" + "text": "mealpy 1 27 8050 1449 0,180 43/35/29/27 \r\n" }, { "output_type": "stream", "name": "stdout", - "text": "mealpy 7 26 8050 1577 0,196 35/27/26/26 \r\n" + "text": "mealpy 7 26 8050 1621 0,201 35/27/26/26 \r\n" }, { "output_type": "stream", "name": "stdout", - "text": "mealpy 42 31 8050 1771 0,220 43/36/33/31 \r\n" + "text": "mealpy 42 31 8050 1772 0,220 43/36/33/31 \r\n" }, { "output_type": "stream", @@ -688,17 +688,17 @@ { "output_type": "stream", "name": "stdout", - "text": "MGS : médiane conflits 43,5 (min 39, max 48), ms/éval moyen 0,194\r\n" + "text": "MGS : médiane conflits 17,0 (min 12, max 22), ms/éval moyen 0,155\r\n" }, { "output_type": "stream", "name": "stdout", - "text": "mealpy : médiane conflits 28,5 (min 26, max 31), ms/éval moyen 0,212\r\n" + "text": "mealpy : médiane conflits 28,5 (min 26, max 31), ms/éval moyen 0,193\r\n" }, { "output_type": "stream", "name": "stdout", - "text": "Rapport ms/éval mealpy/MGS : 1,09x\r\n" + "text": "Rapport ms/éval mealpy/MGS : 1,25x\r\n" }, { "output_type": "stream", @@ -713,32 +713,32 @@ { "output_type": "stream", "name": "stdout", - "text": " cp 25% : MGS 43,5 [39-48] | mealpy 42,0 [35-43] | delta MGS-mealpy +1,5\r\n" + "text": " cp 25% : MGS 32,0 [24-33] | mealpy 42,0 [35-43] | delta MGS-mealpy -10,0\r\n" }, { "output_type": "stream", "name": "stdout", - "text": " cp 50% : MGS 43,5 [39-48] | mealpy 33,5 [27-36] | delta MGS-mealpy +10,0\r\n" + "text": " cp 50% : MGS 22,0 [18-26] | mealpy 33,5 [27-36] | delta MGS-mealpy -11,5\r\n" }, { "output_type": "stream", "name": "stdout", - "text": " cp 75% : MGS 43,5 [39-48] | mealpy 30,0 [26-33] | delta MGS-mealpy +13,5\r\n" + "text": " cp 75% : MGS 19,0 [12-24] | mealpy 30,0 [26-33] | delta MGS-mealpy -11,0\r\n" }, { "output_type": "stream", "name": "stdout", - "text": " cp100% : MGS 43,5 [39-48] | mealpy 28,5 [26-31] | delta MGS-mealpy +15,0\r\n" + "text": " cp100% : MGS 17,0 [12-22] | mealpy 28,5 [26-31] | delta MGS-mealpy -11,5\r\n" }, { "output_type": "stream", "name": "stdout", - "text": "Forme de l'écart qualité : stagnation tardive MGS.\r\n" + "text": "Forme de l'écart qualité : précipitation précoce.\r\n" }, { "output_type": "stream", "name": "stdout", - "text": "Axe coût par step : MGS devant (0,91x le coût mealpy)\r\n" + "text": "Axe coût par step : MGS devant (0,80x le coût mealpy)\r\n" }, { "output_type": "stream", @@ -861,9 +861,9 @@ "- **Qualité finale** : MGS atteint une médiane de 17,0 conflits contre 28,5 pour mealpy, avec séparation totale des gammes : 12-22 contre 26-31. Le pire résultat MGS (22) reste meilleur que le meilleur résultat mealpy (26) ; la domination ne dépend pas d'un chevauchement interprété favorablement.\n", "- **Trajectoire médiane** : MGS part de 32,0 au checkpoint 25 % et continue de descendre — 22,0, puis 19,0 et 17,0 — tandis que mealpy passe de 42,0 à 33,5, puis 30,0 et 28,5. L'écart médian MGS − mealpy se maintient entre −10,0 et −11,5 conflits d'un bout à l'autre de la course. Le classifieur dérivé des quatre checkpoints conclut `précipitation précoce` : l'avantage MGS est acquis dès le premier quart, sans que MGS cesse pour autant d'améliorer son best-so-far jusqu'à la fin.\n", "- **Déterminisme** : conflits finaux **et** quatre checkpoints sont identiques sur les trois répétitions pour les huit couples graine-moteur. La forme observée n'est donc pas un artefact d'une seule trajectoire, et la séparation finale n'est pas du bruit entre répétitions.\n", - "- **Coût par étape** : la cellule calcule dynamiquement le rapport ms/éval du run courant (mealpy y est devant). Les temps absolus ne sont pas recopiés ici, car ils dépendent du matériel ; cet axe ne fonde pas le verdict de qualité.\n", + "- **Coût par étape** : la cellule calcule dynamiquement le rapport ms/éval du run courant (MGS y est devant). Les temps absolus ne sont pas recopiés ici, car ils dépendent du matériel ; cet axe ne fonde pas le verdict de qualité.\n", "\n", - "L'hypothèse de départ — *« possible que les perfs ne suivent pas mealpy sous NumPy optimisé »* — se sépare toujours en deux axes, mais le classement qualité a basculé : MGS domine nettement la qualité à budget égal, mealpy garde l'avantage sur le coût par étape. Les deux PSO ne partagent pas tous leurs paramètres par défaut : ce banc mesure donc les bibliothèques telles qu'un utilisateur les lance, tandis que les checkpoints localisent **quand** leur comportement diverge.\n", + "L'hypothèse de départ — *« possible que les perfs ne suivent pas mealpy sous NumPy optimisé »* — se sépare toujours en deux axes, mais le classement qualité a basculé : MGS domine nettement la qualité à budget égal, et devance aussi le coût par étape. Les deux PSO ne partagent pas tous leurs paramètres par défaut : ce banc mesure donc les bibliothèques telles qu'un utilisateur les lance, tandis que les checkpoints localisent **quand** leur comportement diverge.\n", "\n", "**Avertissement de lecture.** Ce croisement tourne sous le défaut **corrigé** du composé PSO MGS (mutation de l'hôte préservée, `MetaGeneticSharp#50`). Les outputs historiques committés au gitlink précédent montraient la situation inverse — médiane MGS 43,5 [39-48], best-so-far gelé dès le checkpoint 25 % — que la section 3 rejoue ci-dessous comme témoin (`noMutation: true`) et attribue à la mutation désactivée. Le classement ci-dessus est donc la conséquence directe du correctif, pas une propriété du noyau PSO lui-même." ] @@ -886,17 +886,17 @@ { "output_type": "stream", "name": "stdout", - "text": " C# : 6,9 ms total -> 0,014 ms/éval\r\n" + "text": " C# : 5,0 ms total -> 0,010 ms/éval\r\n" }, { "output_type": "stream", "name": "stdout", - "text": " Python : 38,2 ms total -> 0,076 ms/éval\r\n" + "text": " Python : 29,1 ms total -> 0,058 ms/éval\r\n" }, { "output_type": "stream", "name": "stdout", - "text": " rapport Python/C# : 5,56x\r\n" + "text": " rapport Python/C# : 5,77x\r\n" } ], "source": [ @@ -997,42 +997,42 @@ { "output_type": "stream", "name": "stdout", - "text": "témoin noMut=true 0 39 8000 0,099 39/39/39/39 \r\n" + "text": "témoin noMut=true 0 39 8000 0,158 39/39/39/39 \r\n" }, { "output_type": "stream", "name": "stdout", - "text": "témoin noMut=true 1 41 8000 0,093 41/41/41/41 \r\n" + "text": "témoin noMut=true 1 41 8000 0,169 41/41/41/41 \r\n" }, { "output_type": "stream", "name": "stdout", - "text": "témoin noMut=true 7 46 8000 0,085 46/46/46/46 \r\n" + "text": "témoin noMut=true 7 46 8000 0,167 46/46/46/46 \r\n" }, { "output_type": "stream", "name": "stdout", - "text": "témoin noMut=true 42 48 8000 0,081 48/48/48/48 \r\n" + "text": "témoin noMut=true 42 48 8000 0,162 48/48/48/48 \r\n" }, { "output_type": "stream", "name": "stdout", - "text": "défaut corrigé #50 0 12 8000 0,089 32/18/12/12 \r\n" + "text": "défaut corrigé #50 0 12 8000 0,235 32/18/12/12 \r\n" }, { "output_type": "stream", "name": "stdout", - "text": "défaut corrigé #50 1 16 8000 0,094 24/21/19/16 \r\n" + "text": "défaut corrigé #50 1 16 8000 0,188 24/21/19/16 \r\n" }, { "output_type": "stream", "name": "stdout", - "text": "défaut corrigé #50 7 22 8000 0,088 33/26/24/22 \r\n" + "text": "défaut corrigé #50 7 22 8000 0,191 33/26/24/22 \r\n" }, { "output_type": "stream", "name": "stdout", - "text": "défaut corrigé #50 42 18 8000 0,085 32/23/19/18 \r\n" + "text": "défaut corrigé #50 42 18 8000 0,286 32/23/19/18 \r\n" }, { "output_type": "stream", @@ -1342,7 +1342,7 @@ "source": [ "## Résumé et perspectives\n", "\n", - "**Réponse à l'hypothèse de départ.** Sur ce plan apparié — PSO canonique contre `OriginalPSO`, même grille et même coût, budgets mesurés, graines {0, 1, 7, 42} — MGS domine la qualité finale : médiane 17,0 contre 28,5 conflits, avec séparation des gammes 12-22 contre 26-31. mealpy garde l'avantage sur le coût par étape ; son ampleur dépend du matériel et se lit dans l'output, pas dans une valeur figée en prose. L'hypothèse « les perfs ne suivront pas mealpy » est donc réfutée sur l'axe qualité à budget égal ; sur l'axe vitesse brute, mealpy reste devant.\n", + "**Réponse à l'hypothèse de départ.** Sur ce plan apparié — PSO canonique contre `OriginalPSO`, même grille et même coût, budgets mesurés, graines {0, 1, 7, 42} — MGS domine la qualité finale : médiane 17,0 contre 28,5 conflits, avec séparation des gammes 12-22 contre 26-31. MGS devance aussi le coût par étape ; son ampleur dépend du matériel et se lit dans l'output, pas dans une valeur figée en prose. L'hypothèse « les perfs ne suivront pas mealpy » est donc réfutée sur les deux axes mesurés à budget égal — la qualité et le coût par étape.\n", "\n", "**Le mécanisme, localisé et tranché.** Les outputs historiques d'avant le correctif montraient la situation inverse : médiane MGS 43,5, atteinte dès 25 % du budget puis figée — le profil « stagnation tardive ». La section 3 rejoue ce cas en témoin (`noMutation: true`) et tranche l'attribution : le plateau quantifié était un état absorbant parce que le câblage historique désactivait la mutation de l'hôte ; le défaut corrigé fait passer la médiane de 43,5 à 17,0 sur le même plan, verdict `IMPROVES`. La cible d'analyse n'était donc ni la fitness, ni la dynamique de population : un défaut de câblage du composé, isolé et mesuré par la paire.\n", "\n",