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 @@ -451,6 +451,18 @@
"Console.WriteLine($\"PDB simple ({PATTERN.Length} tuiles) : {n5} états en {sw.Elapsed.TotalSeconds:F1}s, distance max = {dmax}\");"
]
},
{
"cell_type": "markdown",
"id": "s03b-pdb-bfs-lecture",
"metadata": {},
"source": [
"### Lecture de la construction : 524 160 = P(16,4) × 12, et la table EST la solution précalculée\n",
"\n",
"La sortie `524 160 états en 1,4 s, distance max = 50` se décompose entièrement à la main. Le BFS rétrograde énumère les positions possibles des 4 tuiles du motif **et** de la case vide dans les 16 cases : 16 × 15 × 14 × 13 = 43 680 arrangements de tuiles, × 12 positions restantes pour la vide = **524 160** états. Le `distance max = 50` dit ensuite que le pire sous-puzzle (les 4 tuiles les plus mal placées) exige 50 coups à lui seul : la table encode donc des optima *partiels* déjà très coûteux, que l'heuristique ira lire en O(1) au lieu de les recalculer. C'est tout le compromis : ~1,4 s de construction une fois, des millions de consultations gratuites ensuite.\n",
"\n",
"Un point qui surprend : le BFS part du BUT et remonte les coups **à l'envers**. Chaque état atteint à profondeur d est donc à distance *exactement* d de l'objectif — la table est un oracle de distance exacte sur le sous-espace, pas une estimation."
]
},
{
"cell_type": "markdown",
"id": "98244622",
Expand Down Expand Up @@ -583,6 +595,16 @@
"}"
]
},
{
"cell_type": "markdown",
"id": "s03b-additive-lecture",
"metadata": {},
"source": [
"### Lecture des groupes : pourquoi la somme des 4 tables reste admissible\n",
"\n",
"La sortie donne quatre tables : trois de 524 160 états (groupes de 4 tuiles) et une de 43 680 (groupe de 3 : P(16,3) = 16 × 15 × 14 = 3 360 arrangements, × 13 positions restantes pour la case vide = 43 680 — le vide est encodé comme pour les groupes de 4). Les distances max se lisent 21, 17, 19 et 16. Le point structurel : chaque coup du 15-puzzle déplace **une seule tuile**, qui appartient à **un seul** groupe — les coûts des groupes sont disjoints par coup, donc leur somme ne peut jamais surestimer la distance réelle. C'est la différence radicale avec la PDB classique de Culberson & Schaeffer : on y prenait le **max** de plusieurs vues du même puzzle ; Korf & Felner partitionnent en groupes **disjoints** pour pouvoir **sommer**. La même somme appliquée à des groupes qui se chevaucheraient casserait l'admissibilité immédiatement (un même coup compté deux fois)."
]
},
{
"cell_type": "markdown",
"id": "05f3f20b",
Expand Down Expand Up @@ -766,6 +788,16 @@
"Console.WriteLine($\"Sur l'instance de démo : Manhattan={Manhattan(INST)}, h_additive={HAdditive(INST)} (additive >= Manhattan attendu)\");"
]
},
{
"cell_type": "markdown",
"id": "s03b-dominance-lecture",
"metadata": {},
"source": [
"### Dominance : additive ≥ Manhattan, lues sur l'instance de démo\n",
"\n",
"La sortie porte trois verdicts distincts. (1) `additive optimal=8 == Manhattan optimal=8` : sur l'instance de test, IDA* trouve le même optimum sous les deux heuristiques — l'optimalité est préservée. (2) `40/40` : sur 40 instances brouillées, h_additive ≤ optimal à chaque fois — l'admissibilité tient en pratique. (3) `Manhattan=26, h_additive=28` : sur l'instance de démo, l'additive **domine** strictement Manhattan. Le lien avec la théorie : Manhattan est exactement la PDB additive des 15 groupes d'**une** tuile — raffiner la partition (1-1-…-1 vers 4-4-4-3) ne peut que resserrer la borne. Un heuristique qui domine *et* reste admissible explore mécaniquement moins de nœuds à optimalité égale : c'est le seul « free lunch » de la recherche heuristique."
]
},
{
"cell_type": "markdown",
"id": "b69f1d52",
Expand Down Expand Up @@ -982,6 +1014,16 @@
"Console.WriteLine(\"additive (4-4-4-3) résout à l'optimum — elle repousse la frontière du résolvable.\");"
]
},
{
"cell_type": "markdown",
"id": "s03b-frontiere-lecture",
"metadata": {},
"source": [
"### Lecture du tableau : ce que « speedup NaN » veut dire\n",
"\n",
"Deux lignes portent `speedup NaN`, et c'est l'information la plus importante du tableau. Sur I1 (optimal 24), les deux heuristiques terminent : 2 114 nœuds contre 732, rapport 2,9 — l'additive fait mieux, mais Manhattan *suffit*. Sur I2 et I3 (optimaux 45 et 53), Manhattan dépasse le budget de 2 M nœuds **sans conclure** : le rapport est `NaN` parce qu'on ne peut pas diviser par un échec. L'additive, elle, conclut à l'optimum en 299 773 et 392 168 nœuds. La leçon n'est pas « 3× plus vite » mais « résout l'irrésolu » : entre les deux colonnes, ce n'est pas la même classe d'instances qui est accessible. La frontière du résoluble a bougé."
]
},
{
"cell_type": "markdown",
"id": "f1c33b0f",
Expand Down Expand Up @@ -1009,6 +1051,16 @@
" *mémoire contre qualité d'heuristique*."
]
},
{
"cell_type": "markdown",
"id": "s03b-attendus-ex1",
"metadata": {},
"source": [
"### Attendus — Exercice 1 (partition 6-6-3)\n",
"\n",
"Ce que vous devez observer si votre implémentation est juste : deux PDB de P(16,6) = 5 765 760 arrangements × 10 = 57 657 600 états chacune, une de P(16,3) × 13 = 43 680 — le temps de construction passe de ~4 s à plusieurs dizaines de secondes (d'où l'avertissement de l'énoncé), les distances max par groupe montent (un groupe de 6 est plus mal plaçable qu'un groupe de 4), et h_additive resserre encore : attendez-vous à ce que I1 descende nettement sous les 732 nœuds de la 4-4-4-3. Anti-piège : la partition doit rester **exactement** disjointe (15 tuiles = 6+6+3) ; réutiliser une tuile dans deux groupes compte ses coups deux fois et casse l'admissibilité — la cellule de vérification du §8 doit rester 40/40."
]
},
{
"cell_type": "markdown",
"id": "3d651408",
Expand Down Expand Up @@ -1143,6 +1195,16 @@
"Console.WriteLine(\"Exercice 2 à compléter : PDB symétrique gratuit (Felner et al. 2004).\");"
]
},
{
"cell_type": "markdown",
"id": "s03b-attendus-ex2",
"metadata": {},
"source": [
"### Attendus — Exercice 2 (PDB symétrique)\n",
"\n",
"La symétrie du 15-puzzle (miroir vertical + renversement des numéros) transforme toute instance en une instance joker : vous obtenez une **seconde heuristique sans nouveau BFS**. L'usage correct est le max des deux vues — admissible car chacune l'est, et strictement meilleur dès qu'une des deux voit mieux. Si vous obtenez exactement les mêmes valeurs qu'avant, votre `Reflect` est probablement l'identité déguisée (indices : le miroir échange les colonnes, et le renversement remappe les numéros t vers 16 − t)."
]
},
{
"cell_type": "markdown",
"id": "b644cc24",
Expand Down Expand Up @@ -1204,6 +1266,18 @@
"Console.WriteLine(\"Exercice 3 à compléter : généralisation au 24-puzzle (5x5, partition 6-6-6-7).\");"
]
},
{
"cell_type": "markdown",
"id": "s03b-attendus-ex3",
"metadata": {},
"source": [
"### Attendus — Exercice 3 (24-puzzle)\n",
"\n",
"Au 24-puzzle (5 × 5), Manhattan est désespérément loose : les instances aléatoires moyennes exigent ~100 coups, et IDA* sous Manhattan explose au-delà de tout budget raisonnable. La structure du code est inchangée (N=5, but 1..24,0) mais les tailles explosent : un groupe de 6 tuiles dans 25 cases donne P(25,6) × 19 = 2 422 728 000, soit ~2,4 milliards d'états — la table ne tient plus en mémoire sans encodage compact. C'est précisément pourquoi Korf & Felner ont poussé les partitions avec symétries et la compression : au 24-puzzle, la PDB n'est plus une optimisation, c'est la condition d'entrée.\n",
"\n",
"**L'arc du notebook** : représenter (permutations), abstraire (sous-espaces), précalculer (BFS rétrograde), sommer (disjonction), vérifier (admissibilité et dominance), mesurer (frontière du résoluble). Ce pipeline est transposable à tout domaine où l'on peut payer du calcul préliminaire pour accélérer des requêtes répétées."
]
},
{
"cell_type": "markdown",
"id": "08e76387",
Expand Down Expand Up @@ -1252,7 +1326,7 @@
"- **Korf, R. E. (1997).** *Finding Optimal Solutions to Rubik's Cube Using Pattern Databases.* AAAI.\n",
"- **Edelkamp, S. & Schrödl, S. (2012).** *Heuristic Search: Theory and Applications.* Morgan Kaufmann.\n",
"\n",
"---\n",
"***\n",
"\n",
"← [Search-3 — Recherche informée](../Part1-Foundations/Search-03-Informed.ipynb)\n",
"\n",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,16 @@
"Console.WriteLine($\"Capacité du sac : {capacity}\");\n"
]
},
{
"cell_type": "markdown",
"id": "s03c-ratio-lecture",
"metadata": {},
"source": [
"### Lecture du banc d'essai : ce que l'ordre des objets encode\n",
"\n",
"La sortie classe A (ratio 1,33) > B = C (1,20) > D (0,50) > E (0,33) pour une capacité de 10. Deux choses se lisent déjà. D'abord, l'ordre du tableau **est** l'heuristique : LDS parlera de « suivre la recommandation » = prendre les objets dans cet ordre tant que le poids le permet. Ensuite, l'égalité parfaite B = C (mêmes poids 5, valeur 6) fabrique une **indifférence** : l'heuristique ne peut pas les départager, et c'est exactement là que les écarts paieront — la solution optimale [B, C] consiste à *refuser* A (le mieux classé !) pour loger la paire que la capacité (10 = 5 + 5) accueille exactement."
]
},
{
"cell_type": "markdown",
"id": "27e86ae8",
Expand Down Expand Up @@ -217,6 +227,16 @@
"Console.WriteLine($\"Greedy (k=0) : valeur={greedyV}, sélection=[{string.Join(\", \", greedySel)}], nœuds={greedyNodes}\");\n"
]
},
{
"cell_type": "markdown",
"id": "s03c-greedy-lecture",
"metadata": {},
"source": [
"### Pourquoi le glouton échoue ici (et pourquoi c'est instructif)\n",
"\n",
"`valeur=10, sélection=[A, D], nœuds=5` : le glouton prend A (ratio max, poids 6), ne peut plus loger ni B ni C (6+5 > 10), recolle D (poids 4, valeur 2) et s'arrête à 10. La solution optimale est [B, C] = 12 — deux objets *mieux notés en volume* dont la somme (10) remplit le sac exactement. L'échec n'est pas un accident du banc : il est structurel (le glouton 0/1 n'a pas de ratio d'approximation borné en général). Les 5 nœuds disent aussi son prix : un parcours linéaire. La question que LDS pose est : *peut-on réparer quelques décisions du glouton sans payer le 2ⁿ de l'énumération ?*"
]
},
{
"cell_type": "markdown",
"id": "72895213",
Expand Down Expand Up @@ -387,6 +407,16 @@
"}\n"
]
},
{
"cell_type": "markdown",
"id": "s03c-lds-lecture",
"metadata": {},
"source": [
"### Lecture du tableau LDS : l'optimum est à k=1, le coût croît régulièrement\n",
"\n",
"Trois lectures. (1) La colonne valeur saute de 10 (k=0) à 12 (k=1) puis **ne bouge plus** : un seul écart au glouton — refuser A — suffit à atteindre l'optimum. (2) Les nœuds montent 6, 13, 21, 28, 33, 34 : à k fixé, LDS explore les chemins à au plus k écarts ; k=5 = n couvre tout l'arbre (34 s'approche des 32 feuilles plus les nœuds internes revisités). (3) La sélection [B, C] est stable dès k=1 : LDS ne « change pas d'avis » en explorant plus, il confirme. Les deux warnings `CS8632` de la sortie sont bénins : des annotations de nullabilité `?` utilisées hors contexte `#nullable` (le gabarit interactif compile sans le flag) — ils n'affectent ni l'exécution ni les résultats."
]
},
{
"cell_type": "markdown",
"id": "0880099f",
Expand Down Expand Up @@ -605,6 +635,16 @@
"Console.WriteLine($\"=> LDS atteint l'optimum dès k*={kStar}, en {ldsNodesStar} nœuds ({100.0*ldsNodesStar/exNodes:F1}% de l'exhaustif).\");\n"
]
},
{
"cell_type": "markdown",
"id": "s03c-crossover-lecture",
"metadata": {},
"source": [
"### La colonne « % exhaustif » : où LDS cesse d'être une bonne affaire\n",
"\n",
"La dernière colonne est la plus parlante : LDS(1) atteint l'optimum pour **40,6 %** du coût de l'énumération (13 nœuds contre 32). Mais la ligne LDS(4) franchit **103,1 %** et LDS(5) 106,2 % : passé un certain k, LDS explore *plus* que l'énumération exhaustive — le décompte par écarts revisite des chemins déjà vus et ajoute du travail. La niche de LDS est donc exactement : **une heuristique assez bonne pour que l'optimal soit à petit k**. Quand l'heuristique est mauvaise (exercice 3), le k optimal monte, la combinatoire gonfle, et LDS dégénère — sans jamais perdre la garantie de complétude à k = n."
]
},
{
"cell_type": "markdown",
"id": "8242686f",
Expand Down Expand Up @@ -718,6 +758,16 @@
"Console.WriteLine(\"Exercice 1 à compléter\");\n"
]
},
{
"cell_type": "markdown",
"id": "s03c-attendus-ex1",
"metadata": {},
"source": [
"### Attendus — Exercice 1 (ILDS)\n",
"\n",
"Le tableau attendu : k = 0..n en boucle, nœuds cumulés ; la valeur stagne à 12 dès k=1, donc ILDS s'arrête à k=2 si votre critère est « deux tours sans amélioration ». Anti-piège : n'interrompez pas au premier k sans amélioration — sur d'autres instances l'optimum peut réapparaître à k+1 après un plateau ; c'est le compromis arrêt-anticipé classique."
]
},
{
"cell_type": "markdown",
"id": "52ccd683",
Expand Down Expand Up @@ -777,6 +827,16 @@
"Console.WriteLine(\"Exercice 2 à compléter\");\n"
]
},
{
"cell_type": "markdown",
"id": "s03c-attendus-ex2",
"metadata": {},
"source": [
"### Attendus — Exercice 2 (passage à l'échelle)\n",
"\n",
"À n=18 : l'énumération = 2¹⁸ = 262 144 feuilles ; LDS à k≤3 explore de l'ordre de la somme des binomiaux C(18, i) pour i ≤ 3, soit ~1 000 nœuds — le ratio se creuse avec n tant que l'optimum reste à petit k. Observez le basculement : si vous générez des ratios « adverses » (l'optimal exige de refuser les 4 premiers objets), LDS(3) ne suffit plus et la courbe nœuds(k) croise la ligne 2ⁿ."
]
},
{
"cell_type": "markdown",
"id": "da81ecbe",
Expand Down Expand Up @@ -837,6 +897,16 @@
"Console.WriteLine(\"Exercice 3 à compléter\");\n"
]
},
{
"cell_type": "markdown",
"id": "s03c-attendus-ex3",
"metadata": {},
"source": [
"### Attendus — Exercice 3 (sensibilité à l'heuristique)\n",
"\n",
"Avec un ordre aléatoire des objets, le k optimal grimpe vers n/2 et le coût LDS rejoint l'énumération — LDS n'a pas de magie intrinsèque, il *emprunte* la qualité de l'heuristique. La courbe à tracer : k* (l'écart de l'optimal au classement) en fonction du nombre d'inversions de l'ordre testé. Elle doit être grossièrement croissante."
]
},
{
"cell_type": "markdown",
"id": "493df909",
Expand Down
Loading
Loading