Skip to content

feat(search,#17937): Search-07 -- analyse de convergence par minimax memoise (complement #17967) - #17991

Closed
jsboige wants to merge 0 commit into
mainfrom
feature/17937-nim-misere
Closed

jsboige wants to merge 0 commit into
mainfrom
feature/17937-nim-misere

Conversation

@jsboige

@jsboige jsboige commented Sep 26, 2026 •

Copy link
Copy Markdown
Owner

Grain: MED/notebook-python — lane myia-po-2027:CoursIA — prev: DEEP/notebook-lean #17530

Summary

Réduction après duplication : la livraison principale de #17937 (variante misère du Nim + témoin minimax) a été faite par #17967 (MERGÉE, NimMisere(NimGame) + valeur_misere lru_cache) pendant que cette PR était en préparation — la partie misère de cette PR est retirée au profit de la version canonique déjà sur main. Ce PR ne porte plus que le delta que #17967 n'a pas couvert : la cellule d'analyse de convergence (remplacement 1:1, cellule 26), dont la version sur main reste l'originelle :

  1. _minimax_memo — minimax mémoïsé (clé (etat, joueur_max)) : l'énumération des actions optimales d'une position devient quasi instantanée sur TicTacToe où les transpositions sont massives.
  2. actions_optimales en ensemble — la version de main compare le coup de MCTS à une seule action optimale (celle de minimax(jeu, etat)) : au TicTacToe vide, plusieurs ouvertures sont équivalentes et le taux de convergence est sous-estimé (biais de mesure). La comparaison à l'ensemble des actions équivalentes corrige le biais.
  3. Graines RNG par répétition — random.seed(seed * 10_000 + rep) : l'analyse de convergence devient reproductible (seed 42 explicite) tout en exposant la variance naturelle de MCTS.
  4. Baseline « choix uniforme » dans le tracé — une ligne de référence 100 / nb_actions % sur le sous-graphe du taux : sans elle, un taux de 40 % ne se lit pas (est-ce bon ? le hasard ferait 11 % au TicTacToe vide).

Aucune autre cellule modifiée : la structure est celle de main (43 cellules), le contenu misère de #17967 est intact, vérifié par assertions pré-commit (class NimMisere(NimGame), valeur_misere, strategie_nim_misere présents ; bloc misère de l'ancienne version absent).

Résultats mesurés

Re-exécution complète (papermill, kernel python3) : 43 cellules, 16 code, 0 erreur, 0 cellule non exécutée. Sortie de la cellule de convergence :

Valeur Minimax de la racine : 0
Actions optimales a la racine : [0, 1, 2, 3, 4, 5, 6, 7, 8] (le choix uniforme ferait 11%)

   iterations  taux_optimal  valeur_moyenne  temps_moyen
0          10         100.0        0.750000     0.000231
1          50         100.0        0.651901     0.001317
2         100         100.0        0.538260     0.003332
3         500         100.0        0.511441     0.018091
4         1000         100.0        0.497515     0.035611
5         5000         100.0        0.486724     0.215022

La sortie fait voir le biais corrigé : au TicTacToe vide (nul parfait), les 9 ouvertures sont toutes minimax-optimales — l'ancienne version comparait le coup de MCTS à une seule d'entre elles et sous-estimait le taux d'un facteur ~9 ; corrigé, le taux est 100 % à tous les budgets, et la ligne « choix uniforme : 11 % » donne la lecture sans laquelle un taux nu ne veut rien dire. La valeur estimée converge proprement 0.75 → 0.487 vers la valeur Minimax 0.

Environnement

Papermill kernel python3 (venv projet, pyspiel 2.0.2 installé règle F au cycle précédent).

Traçabilité duplication

See #17937 — livraison principale déjà mergée (#17967) ; fermeture au coordinateur.

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

@github-actions

Copy link
Copy Markdown
Contributor

PR gate absent du rollup (advisory, #10928)

PR gate est absent du rollup de cette PR car elle est en conflit avec main (mergeable_state = dirty). Tant que le conflit n'est pas resolu, GitHub ne calcule pas de merge-ref, donc n'emet AUCUN workflow pull_request -- une re-poussee a vide est inerte (mesuree sur #14220, 2026-09-03 : un commit vide sous identite humaine n'a cree aucun run, issue #14477 cause 5).

  • Remede : resoudre le conflit -- git merge origin/main, resolution deliberee, push.
  • Ne pas depenser un commit vide : il ne sera pas lu tant que la PR reste dirty.

Cause mesuree : mergeable_state=dirty (PR en conflit avec main)

@jsboige jsboige closed this Sep 26, 2026
@jsboige
jsboige force-pushed the feature/17937-nim-misere branch from 5e2a9db to fd9f72d Compare September 26, 2026 19:52
@jsboige jsboige changed the title feat(search,#17937): Search-07 -- variante misere du Nim + minimax memoise pour la convergence feat(search,#17937): Search-07 -- analyse de convergence par minimax memoise (complement #17967) Sep 26, 2026
@jsboige

jsboige commented Sep 26, 2026

Copy link
Copy Markdown
Owner Author

Réduction après duplication (commentaire de lane) : #17967 (lane myia-po-2025:CoursIA, MERGÉE 19:14Z) a livré la partie misère de #17937 pendant la préparation de cette PR — sa version (sous-classe NimMisere(NimGame) + témoin valeur_misere lru_cache) devient la canonique. La branche a été reconstruite depuis origin/main et réduite à son seul delta réel : la cellule 26 d'analyse de convergence, que #17967 n'a pas touchée et dont la version sur main reste l'originelle (action unique biaisée, non seedée, sans baseline). Commit fd9f72df14fe, notebook re-exécuté (43 cellules, 16 code, 0 erreur). Titre et body mis à jour en conséquence.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-gate-conflict PR gate absent: PR en conflit avec main, aucun run pull_request tant que le conflit dure (#14477)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant