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
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,16 @@
"display(AnalyzePure(rps));"
]
},
{
"cell_type": "markdown",
"id": "lecture-maximin-minimax-1",
"metadata": {},
"source": [
"### Lecture — maximin et minimax en pur : aucun point-selle\n",
"\n",
"Sur Matching Pennies, l'analyse rend **maximin(Row) = −1,0** (Row choisit `Pile`, qui lui garantit −1) et **minimax(Col) = +1,0** (Col choisit `Pile`, qui plafonne Row à +1). L'écart affiché — le « gap » — vaut **2,0** ; la ligne `=> Pas de point-selle en strategies pures` en découle. Pierre-Feuille-Ciseaux donne le **même verdict** (maximin −1, minimax +1, gap 2,0), par symétrie cyclique de ses gains. La conclusion est le moteur de tout le notebook : **dès que maximin ≠ minimax, aucun couple d'actions pures n'est un équilibre** ; il faut recourir aux stratégies mixtes. Le tableau 3×3 qui suit est précisément le contre-exemple positif (un jeu, lui, avec point-selle)."
]
},
{
"cell_type": "markdown",
"id": "51fe42e5",
Expand Down Expand Up @@ -475,6 +485,16 @@
"display(AnalyzePure(saddle));"
]
},
{
"cell_type": "markdown",
"id": "lecture-point-selle",
"metadata": {},
"source": [
"### Lecture — un vrai point-selle : la valeur du jeu est 5\n",
"\n",
"Ce tableau 3×3 est le contre-exemple de la cellule précédente. L'analyse rend **maximin(Row) = 5** (Row joue `R2`) et **minimax(Col) = 5** (Col joue `C2`) — ils **coïncident**, donc **la valeur du jeu est 5** et le couple **(R2, C2) est un équilibre en stratégies pures**. Ce n'est pas fortuit : la ligne `R2` est faiblement dominante (6≥1, 5≥3, 7≥2) et garantit ≥ 5 contre n'importe quelle colonne, tandis que `C2` plafonne Row à ≤ 5 contre n'importe quelle ligne. Le point-selle vit exactement là où la « pire » garantie de Row (5) égale le « meilleur » plafond de Col (5) : aucun joueur n'a intérêt à dévier, ce que la ligne `Point-selle ! Valeur du jeu = 5.0000` consigne."
]
},
{
"cell_type": "markdown",
"id": "65e62449",
Expand Down Expand Up @@ -1138,6 +1158,16 @@
"display(CrossValidateGambit(asym));"
]
},
{
"cell_type": "markdown",
"id": "lecture-crossvalidation-3moteurs",
"metadata": {},
"source": [
"### Lecture — trois moteurs LP, un même verdict (SOTA-OK)\n",
"\n",
"Le benchmark croise **trois résolveurs indépendants** : le simplexe from-scratch de la tranche 1, Google.OrTools GLOP (tranche 2) et Gambit en CLI (tranche 3). Pour les trois jeux, la **valeur `v` est identique au bruit machine près** : `v = 0` pour Matching Pennies et Pierre-Feuille-Ciseaux, `v = 0,71428571` pour le jeu asymétrique, avec `|v1 − v2| ≈ 2,2e-16` et `|v2 − v3| ≈ 1,3e-12`. Les stratégies optimales **concordent aussi** : `σ = [0,5; 0,5]` (MP), `[0,333; 0,333; 0,333]` (RPS) et `[0,5714; 0,4286]` (asymétrique), mêmes valeurs sous les trois moteurs. **Trois implémentations différentes convergent vers le même équilibre** : c'est le sens du verdict SOTA-OK. Le `sanity check σ'Bτ` (nul, `attendu = 0`) confirme que la matrice est bien à somme nulle — la forme de vérification à garder pour tout jeu de ce type."
]
},
{
"cell_type": "markdown",
"id": "2d881f90",
Expand Down Expand Up @@ -1255,6 +1285,16 @@
"display(SolveAndShow(rps));"
]
},
{
"cell_type": "markdown",
"id": "lecture-mixte-uniforme",
"metadata": {},
"source": [
"### Lecture — la stratégie mixte uniforme : l'équilibre symétrique\n",
"\n",
"La cellule rend **σ* = τ* = [0,5; 0,5]** pour Matching Pennies et **σ* = τ* = [0,333; 0,333; 0,333]** pour Pierre-Feuille-Ciseaux, avec `valeur du jeu = 0` dans les deux cas. Le patron est net : pour un jeu **symétrique** (matrice antisymétrique, `A[i,j] = −A[j,i]`), la valeur ne peut être que **0**, et l'unique équilibre est la **distribution uniforme** qui rend l'adversaire indifférent entre ses actions. C'est la traduction concrète du théorème minimax : la stratégie mixte de Row égalise les gains espérés de chaque action de Col, de sorte qu'aucun choix adverse ne vaut mieux qu'un autre. Révéler cette répartition uniforme ne concède donc **rien** — c'est le point à retenir avant la section 5 (jeu asymétrique, où la valeur devient, elle, positive)."
]
},
{
"cell_type": "markdown",
"id": "601a2be8",
Expand Down Expand Up @@ -1361,6 +1401,16 @@
"display(sb2.ToString());"
]
},
{
"cell_type": "markdown",
"id": "lecture-balayage-asym",
"metadata": {},
"source": [
"### Lecture — la valeur 5/7 et le balayage : là où le min est maximisé\n",
"\n",
"Le jeu asymétrique a pour valeur **v = 0,7143 (= 5/7)** et **σ* = τ* = [0,5714; 0,4286]**. La valeur est **favorable à Row** (v > 0, alors que les jeux symétriques valaient 0). Le **balayage** rend le mécanisme visible : en posant `p = P(R0)`, Row espère `gain C0 = 2p − 1(1−p) = 3p − 1` et `gain C1 = −p + 3(1−p) = 3 − 4p`. La colonne `min(pire)` est `min(3p−1, 3−4p)` ; son **maximum est atteint quand les deux droites se croisent** : `3p − 1 = 3 − 4p ⟹ p = 4/7 ≈ 0,5714`, d'où `v = 3(4/7) − 1 = 5/7 ≈ 0,7143`. Le balayage (pas de 0,1) n'échantillonne que des points — il approche ce pic entre `p = 0,50` et `p = 0,60` — et c'est la résolution analytique qui donne la valeur exacte : Row pèse 4/7 sur `R0` et 3/7 sur `R1`, rendant Col indifférent (gain C0 = gain C1 = 5/7)."
]
},
{
"cell_type": "markdown",
"id": "a7f8efb1",
Expand Down Expand Up @@ -1460,6 +1510,16 @@
"display(VerifyDuality(asym));"
]
},
{
"cell_type": "markdown",
"id": "lecture-dualite-forte",
"metadata": {},
"source": [
"### Lecture — dualité forte : le théorème minimax est un cas de programmation linéaire\n",
"\n",
"Les deux vérifications rendent **v = w** : pour RPS, `v = w = 0` ; pour le jeu asymétrique, `v = w = 0,714286`. C'est le **théorème de dualité forte** — le primal (Row maximise `v`) et le dual (Col minimise `w`) ont **la même valeur optimale** — spécialisé au jeu à somme nulle, ce qui n'est autre que le **théorème minimax de Von Neumann**. La ligne **complementary slackness** le confirme de façon mécanique : pour **chaque** action de Col, `gain de Row ≥ v ? True` — les écarts sont tous non négatifs (`0` pour RPS, `0,7143` pour chacune des deux actions du jeu asymétrique). Aucune colonne ne rapporte à Col moins que la valeur du jeu, donc la stratégie mixte de Row **neutralise simultanément** toutes les actions adverses : c'est exactement la condition d'optimalité que la dualité LP encode."
]
},
{
"cell_type": "markdown",
"id": "7089db32",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,16 @@
csharp_sha: 20e2f0ba04aa988274aa7fa9e3fa33576771e2eb
content_python_sha: bdcfa5bd0d7fe172066c114a75524c1020e5be15c1683186b346bfe3ed122ddd
content_csharp_sha: ff1061684ea9c35cf46f7bcf5a22609a5e9124a20cfe6d77b82b261fb78a5d9f
- date: "2026-09-01"
by: myia-po-2027:CoursIA
python_sha: 21a151cdb58ff30a89e05805e07f79a0f01f2eda
csharp_sha: 0659fbfc20089ec587396d082f41f0e69f7067ef
content_python_sha: bdcfa5bd0d7fe172066c114a75524c1020e5be15c1683186b346bfe3ed122ddd
content_csharp_sha: 2c2a2a8103e09629a8afb2f0f9f64346a72a9578356bf40c624e2798fe29a060
known_differences:
- '2026-08-31 : ATTESTATION UNILATERALE (PR #13659, lane myia-ai-01:CoursIA) -- reparation d''echappements JSON manges dans le markdown du cote C#. CAUSE : dans le .ipynb, la sequence dollar-\bot-dollar ecrite avec UN SEUL antislash est lue par le parseur JSON comme l''echappement \b (backspace, U+0008) ; la source chargee porte un caractere de controle et le notebook rend un dollar-ot-dollar prive de sa commande LaTeX. FIX : doubler l''antislash (\\bot). Le DRIFT est UNILATERAL parce que le DEFAUT l''est : la contrepartie GameTheory-05-ZeroSum-Minimax.ipynb (Python), 19 cellules markdown, a ete scannee sous controle positif (le litteral defectueux passe a json.loads doit rendre U+0008 -- assertion verifiee avant le scan) et ne porte AUCUN caractere de controle U+0008/U+000B/U+000C. Il n''y a donc rien a reparer de ce cote : l''attestation ne consacre aucune asymetrie de contenu. PORTEE DU DIFF cote repare (comparaison des JSON parses origin/main -> HEAD) : markdown uniquement, 0 cellule code touchee, 0 sortie modifiee, 0 execution_count deplace, 0 cellule ajoutee ou retiree.'
- "Socle pedagogique commun : jeux a somme nulle, theoreme minimax (valeur du jeu v), strategies mixtes optimales sigma/tau via programmation lineaire."
- "parite lib-vs-lib native-both (#10382) : chaque cote atteint un moteur LP de production de son ecosysteme. Python = `scipy.optimize.linprog` + nashpy. C# = `Google.OrTools.LinearSolver` solveur GLOP (NuGet, deja en service dans CSP-4/6/8) en Tranche 2 + `gambit-lp.exe` (McKelvey-McLennan-Turocy 2016, GPL-2.0, externe) en Tranche 3 via Process.Start. TROIS moteurs LP convergeant sur la meme valeur de jeu et la meme strategie (Matching Pennies v=0 sigma=[0.5,0.5] ; RPS v=0 sigma=[1/3,1/3,1/3] ; asymetrique 2x2 v=0.714 sigma=[0.571,0.429], |delta v| <= 2e-16 cross-tranches), capture dans les cellules `8b4e1d23` (Tranche 1 vs Tranche 2) et `98a90823` (Tranche 1 vs Tranche 2 vs Tranche 3)."
- "Tranche 1 preservee byte-identique : le simplexe de Dantzig from-scratch (`SimplexMax` + regle de Bland anti-cyclage + `SolveMatrixGame` formulation Col+duales) reste comme moteur pedagogique, en PLUS du Glop industriel (Tranche 2) et de Gambit (Tranche 3). Mandat user : from scratch EN PLUS, jamais A LA PLACE. Croisement strict : trois moteurs (Dantzig vs Glop vs Gambit) ET deux formulations (Col+duales vs Row directe) donnent le meme resultat = controle le plus exigeant qu'on puisse ecrire sur ce theoreme."
- "Tranche 3 (Gambit CLI) : serialisation du jeu en format `.nfg` Gambit (NFG 1 R \"...\" { \"Row\" \"Col\" } { m n } + 2*m*n payoffs en convention j-i lex par `ToNfg`), invocation `gambit-lp.exe -q -d 6 <tmp.nfg>` par Process.Start, parsing CSV des lignes `NE,p1,...,pm,c1,...,cn` en tuples (sigma, tau) par `RunGambitLP`. Binaire cherche a `%LOCALAPPDATA%\\Gambit\\Gambit\\gambit-lp.exe` puis fallback Program Files x86 (portable cross-machine, precedent GT-10 cell 8). Cross-validation trois-moteurs (Tranche 1 vs Tranche 2 vs Tranche 3) sur mp/rps/asym : toutes les valeurs et strategies coincident au epsilon machine (max |delta v| = 2.22e-16 sur asym 2x2), sanity check zero-sum sigma' B tau == -v OK sur les trois jeux. Gate nashpy INTRINSIC LEVE par ai-01 msg-20260812T112529-87ciq6 : Gambit CLI = bucket-2 invocable (meme raisonnement que Planners-4 Fast Downward dans #10401/#10413), bucket-2 / bucket-3 frontiere d'invocabilite pas de langage."
- '2026-09-01 : ENRICHISSEMENT MARKDOWN-ONLY COTE C# (commit 2e899098c8c, lane myia-po-2027:CoursIA) -- densite d''interpretation 890 -> 1217 c/cell (seuil 1200). AJOUT de 6 cellules markdown « Lecture du resultat » qui lisent les valeurs commitees : maximin/minimax en pur (gap 2,0, pas de point-selle) ; point-selle valeur 5 en (R2,C2) ; cross-validation 3 moteurs (max |delta v| <= 1.3e-12) ; strategies mixtes uniformes [0,5]/[1/3] ; valeur 5/7 et croisement p=4/7 du balayage asymetrique ; dualite forte v=w. La contrepartie GameTheory-05-ZeroSum-Minimax.ipynb (Python) porte DEJA des cellules d''interpretation equivalentes aux points de calcul correspondants (cellules 6/10/14/20 : absence de point-selle, resolution par programmation lineaire, visualisation du theoreme, strategie optimale du Colonel Blotto). Le DRIFT est COTE C# UNIQUEMENT parce que le DEFICIT d''interpretation l''est : cette PR ALIGNE le cote C# sur la couverture deja presente chez son jumeau Python, elle ne cree donc aucune asymetrie de contenu nouvelle -- elle resorbe au contraire l''ecart de couverture entre les deux cotes. La parite lib-vs-lib native-both n''est PAS affectee (les cellules de calcul Tranche 1/2/3 sont inchangees). PORTEE DU DIFF (comparaison des JSON parses origin/main -> HEAD) : markdown uniquement, 0 cellule code touchee, 0 sortie modifiee, 0 execution_count deplace, 6 cellules ajoutees.'
Loading