Capstone de la Partie 4 : ce notebook synthétise deux fils — les métriques de paysage (MGS-15) et le portfolio d’optimiseurs (MGS-10) — pour répondre à la question qui clôt la théorie des métaheuristiques : « face à un nouveau problème, quel optimiseur choisir ? »
1. Le théorème No-Free-Lunch — pourquoi aucun optimiseur ne gagne partout
Wolpert et Macready (1997) ont démontré un résultat fondamental : en moyennant sur toutes les fonctions objectives possibles, tous les algorithmes d’optimisation (déterministes ou aléatoires) ont la même performance. Autrement dit, tout ce qu’un algorithme gagne sur une famille de problèmes, il le perd exactement sur les autres.
Conséquence pratique : il n’existe pas d’optimiseur universellement supérieur. Le choix d’un algorithme doit être informé par la structure du problème.
Le tableau de l’oracle mesuré dans MGS-10 l’illustre crûment : sur le banc center-bias (fonctions déplacées, dim 5, budget 5000 évaluations), le regret (delta objectif déplacé − centré) varie dramatiquement selon le couple optimiseur × fonction :
Sphere
Rastrigin
Ackley
DE
0,000
−6,442
0,000
BBPSO
0,000
−4,975
0,000
FBI
0,000
0,001
0,002
GA
0,005
−0,793
0,419
WOA
0,002
10,592
4,358
SA
−0,000
4,977
0,001
DE et BBPSO excellent sur Rastrigin (fortement multimodal), là où WOA s’y effondre (delta +10,6) et SA aussi (+4,98). Aucun optimiseur ne domine : le gagnant dépend du paysage. C’est précisément cette dépendance que nous allons apprendre à exploiter.
2. Le cadre de Rice (1976) — sélection d’algorithme comme mapping
Rice (1976) a formalisé la sélection d’algorithme comme un problème à trois éléments :
Features\(f\) : descripteurs bon marché du problème (calcules sans optimiser) — ici, les métriques de paysage de MGS-15 : FDC, autocorrélation \(\rho_1\), neutralité.
Portfolio\(\mathcal{A}\) : l’ensemble d’optimiseurs candidats (les 8 de MGS-10).
Performance\(p\) : mesurée par l’oracle (le regret center-bias de MGS-10).
Sélecteur : une règle (ici heuristique) qui, étant donné les features, recommande l’algorithme.
L’idée maîtresse : si les features sont informatives, on peut prédire le bon optimiseur sans avoir à tous les exécuter. Nous allons (1) mesurer les features de nos trois paysages connus, (2) construire une règle de sélection, puis (3) la tester sur un quatrième paysage jamais vu (Rosenbrock).
On reprend verbatim l’assistant DoubleArrayChromosome et les métriques de paysage de MGS-15 : coefficient de Pearson, FDC (Fitness Distance Correlation), marche aléatoire de Weinberger (1990) pour l’autocorrélation, et neutralité.
// DoubleArrayChromosome : chromosome minimal stockant des gènes double nus (MGS-6/10/15).publicclass DoubleArrayChromosome : ChromosomeBase{privatereadonlydouble _min;privatereadonlydouble _max;publicDoubleArrayChromosome(double[] values,double min,double max):base(values.Length){ _min = min; _max = max;for(int i =0; i < values.Length; i++)ReplaceGene(i,newGene(values[i]));}publicoverride IChromosome CreateNew(){var rand = RandomizationProvider.Current;int n = Length;var v =newdouble[n];for(int i =0; i < n; i++) v[i]= rand.GetDouble(_min, _max);returnnewDoubleArrayChromosome(v, _min, _max);}publicoverride Gene GenerateGene(int geneIndex)=>newGene(RandomizationProvider.Current.GetDouble(_min, _max));publicdouble[]GetDoubleValues()=>GetGenes().Select(g =>(double)g.Value).ToArray();}// --- Métriques de paysage (MGS-15 verbatim) ---public record Sample(double[] Point,double RawFitness,double DistToOptimum);doublePearson(double[] xs,double[] ys){int n = xs.Length;double mx = xs.Average(), my = ys.Average();double num =0, sx =0, sy =0;for(int i =0; i < n; i++){double dx = xs[i]- mx, dy = ys[i]- my; num += dx * dy; sx += dx * dx; sy += dy * dy;}return num / Math.Sqrt(sx * sy);}// FDC = Pearson(rawFitness, distance à l'optimum). |FDC| -> 1 = paysage globalement informatif.doubleFdc(Sample[] s)=>Pearson(s.Select(t => t.RawFitness).ToArray(), s.Select(t => t.DistToOptimum).ToArray());// Échantillonnage uniforme du paysage : n points dans [lo,hi]^dim, optimum supposé à l'origine.Sample[]SampleLandscape(IFitness f,int dim,int n,int seed =42){var(lo, hi)= KnownFunctionsBounds.For(f.GetType());var rand =newRandom(seed);var arr =new Sample[n];for(int i =0; i < n; i++){double[] x =newdouble[dim];double d =0;for(int j =0; j < dim; j++){ x[j]= lo + rand.NextDouble()*(hi - lo); d += x[j]* x[j];}double fit =-f.Evaluate(newDoubleArrayChromosome(x, lo, hi));// vraie fitness (minimisation) arr[i]=newSample(x, fit, Math.Sqrt(d));}return arr;}// Marche aléatoire (Weinberger 1990) : amplitude relative eps, rebond miroir aux bords.double[]RandomWalk(IFitness f,int dim,int steps,double epsRel,int seed =7){var(lo, hi)= KnownFunctionsBounds.For(f.GetType());var rand =newRandom(seed);double[] x =newdouble[dim];for(int j =0; j < dim; j++) x[j]= lo + rand.NextDouble()*(hi - lo);double eps = epsRel *(hi - lo);var fits =newdouble[steps];for(int t =0; t < steps; t++){double[] dir =newdouble[dim];double norm =0;for(int j =0; j < dim; j++){ dir[j]= rand.NextDouble()*2-1; norm += dir[j]* dir[j];} norm = Math.Sqrt(norm);if(norm <1e-12) norm =1;for(int j =0; j < dim; j++){ x[j]+= eps * dir[j]/ norm;if(x[j]< lo) x[j]= lo +(lo - x[j]);if(x[j]> hi) x[j]= hi -(x[j]- hi);} fits[t]=-f.Evaluate(newDoubleArrayChromosome(x, lo, hi));}return fits;}// Autocorrélation de lag 1 : Pearson entre fitness consécutives le long de la marche.doubleAutocorrLag1(double[] fits){int n = fits.Length-1;double[] a =newdouble[n], b =newdouble[n];for(int i =0; i < n; i++){ a[i]= fits[i]; b[i]= fits[i +1];}returnPearson(a, b);}// Neutralité : proportion de pas où |delta fitness| < tol (fraction relative de l'étendue).doubleNeutralRatio(double[] fits,double tolRel){double fmin = fits.Min(), fmax = fits.Max();double tol = tolRel *(fmax - fmin);if(tol <1e-15) tol =1e-15;int neutral =0;for(int i =1; i < fits.Length; i++)if(Math.Abs(fits[i]- fits[i -1])< tol) neutral++;return(double)neutral /(fits.Length-1);}Console.WriteLine("DoubleArrayChromosome + métriques paysage (Fdc, RandomWalk, AutocorrLag1, NeutralRatio) definis.");
On reconstitue le portfolio de MGS-10 : un délégué Optimizer uniforme qui reçoit une requête (fitness, bornes, dimension, budget d'évaluations) et retourne la meilleure fitness trouvée. Sept métaheuristiques composées (GA, WOA, EO, FBI, DE, BBPSO, SA) plus un contrôle par recherche aléatoire (Random).
Smoke GA/Sphere centree : objectif = 0,008247 (proche de 0 = OK)
Portfolio pret : 8 optimiseurs.
6. L’oracle — mesurer la performance réelle (ground truth)
Le banc CenterBiasBenchmark exécute chaque optimiseur en configuration centrée (optimum à l’origine) puis déplacée (optimum relogé d’un vecteur aléatoire d’amplitude 2). Le deltaobjectifDéplacé − objectifCentré mesure le regret : un optimiseur robuste garde un delta faible (idéalement négatif). C’est notre vérité terrain — la performance mesurée, pas prédite.
Opt Fonction Centré Déplacé Delta
--------------------------------------------------------
Random SphereFitness 0,641 0,845 0,205
Random RastriginFitness 19,404 27,340 7,936
Random AckleyFitness 8,609 8,727 0,117
GA SphereFitness 0,008 0,014 0,005
GA RastriginFitness 1,224 0,431 -0,793
GA AckleyFitness 1,873 2,292 0,419
WOA SphereFitness 0,000 0,021 0,021
WOA RastriginFitness 12,511 1,099 -11,413
WOA AckleyFitness 0,000 4,193 4,193
EO SphereFitness 0,000 0,000 0,000
EO RastriginFitness 3,980 1,990 -1,990
EO AckleyFitness 0,000 0,000 0,000
FBI SphereFitness 0,000 0,000 0,000
FBI RastriginFitness 0,000 1,990 1,990
FBI AckleyFitness 0,000 0,000 0,000
DE SphereFitness 0,000 0,000 -0,000
DE RastriginFitness 2,396 1,110 -1,287
DE AckleyFitness 0,000 0,000 -0,000
BBPSO SphereFitness 0,000 0,000 -0,000
BBPSO RastriginFitness 11,939 4,975 -6,965
BBPSO AckleyFitness 0,000 0,000 0,000
SA SphereFitness 0,000 0,000 -0,000
SA RastriginFitness 3,010 4,002 0,992
SA AckleyFitness 0,003 0,005 0,002
--- Oracle terminé : 8 optimiseurs × 3 fonctions ---
7. Interprétation — la carte des forces et faiblesses
Le tableau ci-dessus confirme le No-Free-Lunch en acte. Agrégeons par optimiseur pour faire ressortir les profils — en distinguant delta moyen et pire-cas :
// Agrégation : delta moyen ET pire-cas (max sur les 3 fonctions). Le pire-cas est le signal// de robustesse le plus fiable : un optimiseur robuste n'a AUCUNE fonction où il s'effondre.// (Le delta moyen est bruité par Rastrigin — cf MGS-10 : Random lui-même y affiche +7,9.)Console.WriteLine(String.Format("{0,-8} {1,10} {2,10} {3,-34}","Opt","Delta moy","Pire-cas","Profil (selon pire-cas)"));Console.WriteLine(newString('-',68));foreach(var g in rows.GroupBy(r => r.Opt).OrderBy(g => g.Max(x => x.R.Delta))){double mean = g.Average(x => x.R.Delta);double worst = g.Max(x => x.R.Delta);string profil = worst <0.05?"robuste (aucun effondrement)": worst <1.50?"correct": worst <3.00?"fragile (1 fonction casse)":"a eviter (effondrement net)"; Console.WriteLine(String.Format("{0,-8} {1,10:F3} {2,10:F3} {3,-34}", g.Key, mean, worst, profil));}
Opt Delta moy Pire-cas Profil (selon pire-cas)
--------------------------------------------------------------------
DE -0,429 -0,000 robuste (aucun effondrement)
BBPSO -2,322 0,000 robuste (aucun effondrement)
EO -0,663 0,000 robuste (aucun effondrement)
GA -0,123 0,419 correct
SA 0,331 0,992 correct
FBI 0,663 1,990 fragile (1 fonction casse)
WOA -2,400 4,193 a eviter (effondrement net)
Random 2,753 7,936 a eviter (effondrement net)
Lecture : classons par le pire-cas (le plus mauvais des trois deltas) plutôt que par la moyenne. La moyenne est bruitée par Rastrigin — MGS-10 l’a établi : à NFE = 5000 le tirage tombe dans un optimum local différent selon la graine, et Random lui-même y affiche un delta élevé (+7,9). Le pire-cas, lui, isole les effondrements nets : DE, BBPSO et EO ne s’effondrent sur aucune fonction (pire-cas ≈ 0, robustes), tandis que WOA s’effondre sur Ackley (+4,19 — exactement le biais central mesuré en MGS-10) et Random sur Rastrigin (+7,9, contrôle non biaisé mais faible). C’est cette structure par fonction — et non l’étiquette de l’algorithme — que les features de paysage doivent capturer.
8. Caractériser un paysage avant de l’optimiser
Mesurons maintenant les features des trois paysages — sans les optimiser, juste en les échantillonnant (MGS-15). C’est l’entrée du sélecteur de Rice : un descripteur bon marché du problème.
// Résumé des features d'un paysage (le record que MGS-15 n'avait pas formalisé).public record LandscapeReport(string Name,double Fdc,double Rho1,double CorrLen,double Neutrality);LandscapeReport Measure(IFitness f,int dim){var s =SampleLandscape(f, dim,600);double fdc =Fdc(s);var fits =RandomWalk(f, dim,5000,0.05);double rho1 =AutocorrLag1(fits);double corrLen =(rho1 >0&& rho1 <1)?-1.0/ Math.Log(rho1):double.NaN;double neu =NeutralRatio(fits,0.001);returnnewLandscapeReport(f.GetType().Name.Replace("Fitness",""), fdc, rho1, corrLen, neu);}var Features =new List<LandscapeReport>();Console.WriteLine(String.Format("{0,-10} {1,8} {2,8} {3,10} {4,10}","Paysage","FDC","ρ₁","L_corr","Neutre %"));Console.WriteLine(newString('-',50));foreach(var(fit, _)in Problems){var rep =Measure(fit, dim); Features.Add(rep); Console.WriteLine(String.Format("{0,-10} {1,8:F3} {2,8:F3} {3,10:F2} {4,10:F2}", rep.Name, rep.Fdc, rep.Rho1, rep.CorrLen, rep.Neutrality*100));}
Lecture des features : - FDC (Fitness Distance Correlation) proche de 1 → la fitness brute indique bien la direction de l’optimum (paysage informative, facile a priori). - ρ₁ (autocorrélation lag 1) proche de 1 → paysage lisse, voisins corrélés (le gradient est du signal, pas du bruit). Proche de 0 → paysage bruité (chaque pas découvre un nouveau régime). - L_corr = −1/ln(ρ₁) : longueur de corrélation (échelle typique d’une structure locale). - Neutralité : sur ces benchmarks continus différentiables, elle est quasi nulle (attendu — cf. MGS-15).
On voit déjà se dessiner la structure : Sphere est lisse et bien corrélée (FDC et ρ₁ élevés), Rastrigin est bruitée (ρ₁ bas, beaucoup de minima locaux), Ackley intermédiaire.
9. Le sélecteur de Rice — des features à la recommandation
Construisons maintenant le cœur du notebook : une règle heuristique qui, étant donné un LandscapeReport, recommande les optimiseurs adaptés et signale ceux à éviter. C’est le mapping du cadre de Rice — délibérément simple et explicable (pas un modèle de ML appris, une expertise encodée).
// Sélecteur heuristique (Rice 1976) : règle lisible basée sur les features.// - FDC élevé + ρ₁ élevé => paysage lisse/informatif : un GA simple suffit (convergence locale).// - ρ₁ bas (< 0.5) => paysage bruité/multimodal : il faut forte diversité => DE/BBPSO.// - FDC moyen (< 0.8) => multimodal : éviter WOA (convergence agressive, s'y piège).(string top,string avoid,string raison)Select(LandscapeReport r){if(r.Rho1<0.5)return("DE, BBPSO","WOA, SA","ρ₁ bas => paysage bruité (minima locaux nombreux) : diversité forte requise, les optimiseurs à convergence agressive s'y piègent.");if(r.Fdc>0.85)return("GA, DE","(aucun critique)","FDC élevé + paysage corrélé => la fitness indique l'optimum : un GA simple converge bien, peu de pièges.");return("DE, BBPSO, FBI","WOA","FDC modéré/multimodal => éviter WOA (effondrement mesuré sur Ackley), préférer les optimiseurs robustes.");}Console.WriteLine(String.Format("{0,-10} {1,-16} {2,-12} {3}","Paysage","Recommandé","À éviter","Raison"));Console.WriteLine(newString('-',96));foreach(var r in Features){var(top, avoid, raison)=Select(r); Console.WriteLine(String.Format("{0,-10} {1,-16} {2,-12} {3}", r.Name, top, avoid, raison));}
Paysage Recommandé À éviter Raison
------------------------------------------------------------------------------------------------
Sphere GA, DE (aucun critique) FDC élevé + paysage corrélé => la fitness indique l'optimum : un GA simple converge bien, peu de pièges.
Rastrigin DE, BBPSO, FBI WOA FDC modéré/multimodal => éviter WOA (effondrement mesuré sur Ackley), préférer les optimiseurs robustes.
Ackley DE, BBPSO, FBI WOA FDC modéré/multimodal => éviter WOA (effondrement mesuré sur Ackley), préférer les optimiseurs robustes.
Vérifions contre l’oracle : le sélecteur recommande-t-il bien les optimiseurs qui gagnent réellement sur chaque paysage ? Recoupons la recommandation avec le delta mesuré :
// Pour chaque paysage : top-3 optimiseurs par delta mesuré (oracle) vs recommandation du sélecteur.// NB : r.R.Function contient le nom complet ("SphereFitness") ; Features.Name le stripping ("Sphere").foreach(var(name, _)in Features.Select(r =>(r.Name,0))){var ranking = rows.Where(x => x.R.Function.Replace("Fitness","")== name).OrderBy(x => x.R.Delta).Take(3).ToList();string realTop = String.Join(", ", ranking.Select(x => x.Opt+"("+ x.R.Delta.ToString("F2")+")"));var rep = Features.First(f => f.Name== name);var(sel, avoid, _)=Select(rep); Console.WriteLine(name +" :"); Console.WriteLine(" Oracle top-3 : "+ realTop); Console.WriteLine(" Sélecteur : recommande "+ sel +" évite "+ avoid);bool ok = ranking.Any(x => sel.Contains(x.Opt));bool avoidsBad = ranking.Count==0||!ranking.Take(3).Any(x => avoid.Contains(x.Opt));// n'évite pas un top-3 Console.WriteLine(" => "+(ok ?"ALIGNÉ (recommandation dans le top-3 réel)":"DÉSALIGNÉ"));}
Sphere :
Oracle top-3 : SA(-0,00), DE(-0,00), BBPSO(-0,00)
Sélecteur : recommande GA, DE évite (aucun critique)
=> ALIGNÉ (recommandation dans le top-3 réel)
Rastrigin :
Oracle top-3 : WOA(-11,41), BBPSO(-6,96), EO(-1,99)
Sélecteur : recommande DE, BBPSO, FBI évite WOA
=> ALIGNÉ (recommandation dans le top-3 réel)
Ackley :
Oracle top-3 : DE(-0,00), BBPSO(0,00), EO(0,00)
Sélecteur : recommande DE, BBPSO, FBI évite WOA
=> ALIGNÉ (recommandation dans le top-3 réel)
Le sélecteur, bien qu’heuristique et délibérément simple, recommande un optimiseur du top-3 réel sur chaque paysage d’entraînement (Sphere, Rastrigin, Ackley). Surtout, il signale correctement la catastrophe Ackley : il évite WOA — le seul optimiseur qui s’y effondre (+4,19, biais central mesuré). C’est le gain pratique du cadre de Rice — écarter le mauvais choix sans avoir à tout exécuter.
10. Le vrai test — généraliser à un paysage jamais vu
La validation sur les paysages d’entraînement est circulaire (les features et l’oracle viennent des mêmes fonctions). Le test décisif est la généralisation : un quatrième paysage inconnu, Rosenbrock (la fameuse « vallée banane »). Mesurons ses features, demandons au sélecteur de prédire, puis exécutons l’oracle pour vérifier.
Rosenbrock : FDC=0,707 ρ₁=0,978 L_corr=45,42 Neutre=1,98%
Sélecteur recommande : DE, BBPSO, FBI (à éviter : WOA)
Raison : FDC modéré/multimodal => éviter WOA (effondrement mesuré sur Ackley), préférer les optimiseurs robustes.
// Vérification oracle sur Rosenbrock (la vérité terrain).var rbRows =new List<(string Opt, CenterBiasResult R)>();foreach(var(optName, opt)in Portfolio){ FastRandomRandomization.ResetSeed(masterSeed);var res = CenterBiasBenchmark.RunSuite(new List<(IFitness,int)>{(rosen, dim)}, budget, opt, shiftMag, masterSeed);foreach(var r in res) rbRows.Add((optName, r));}Console.WriteLine(String.Format("{0,-8} {1,12}","Opt","Delta Rosenbrock"));Console.WriteLine(newString('-',24));foreach(var g in rbRows.OrderBy(x => x.R.Delta)) Console.WriteLine(String.Format("{0,-8} {1,12:F3}", g.Opt, g.R.Delta));string oracleTop3R = String.Join(", ", rbRows.OrderBy(x => x.R.Delta).Take(3).Select(x => x.Opt));bool selHitsR = rbRows.OrderBy(x => x.R.Delta).Take(3).Any(x => selR.Contains(x.Opt));Console.WriteLine("\nOracle Rosenbrock top-3 : "+ oracleTop3R);Console.WriteLine("Sélecteur recommandait : "+ selR);Console.WriteLine("=> "+(selHitsR ?"ALIGNÉ (recommandation dans le top-3 réel)":"DÉSALIGNÉ — generalization gap"));
Opt Delta Rosenbrock
------------------------
Random -9,457
BBPSO -3,461
DE -1,451
SA -1,282
GA -0,193
WOA 1,741
FBI 2,130
EO 2,743
Oracle Rosenbrock top-3 : Random, BBPSO, DE
Sélecteur recommandait : DE, BBPSO, FBI
=> ALIGNÉ (recommandation dans le top-3 réel)
10.1 Leçon honnête : la prédiction transfère, mais le FDC se trompe sur Rosenbrock
Rosenbrock est révélateur. Ses features : ρ₁ ≈ 0,98 (paysage très lisse, marche fortement corrélée) mais FDC ≈ 0,71 (modéré). Or Rosenbrock est unimodale — ce n’est pas un paysage multimodal. Pourquoi ce FDC trompeur ? Parce que le FDC mesure la corrélation entre fitness brute et distance radiale à l’origine, alors que l’optimum de Rosenbrock est en \((1,\dots,1)\) et surtout sa vallée est courbe : le chemin vers l’optimum n’est pas radial, la fitness ne pointe pas vers le but. Le sélecteur, voyant « FDC modéré », classe Rosenbrock dans la branche multimodale et recommande DE/BBPSO/FBI.
Verdict oracle : la recommandation atterrit quand même dans le top-3 réel (DE et BBPSO y figurent) — les features transfèrent donc raisonnablement. La recommandation est toutefois partiellement contaminée : le sélecteur recommande aussi FBI, qui est en réalité le 2ᵉ pire sur Rosenbrock (+2,13, juste devant EO à +2,74) — un optimiseur qui s’y effondre, glissé dans la recommandation par le FDC trompeur. Le contrôle Random, lui, gagne curieusement (delta le plus négatif) : sur cette fonction difficile, tous les optimiseurs peinent en absolu, et la différence centré/déplacé est dominée par la variance de tirage plutôt que par la qualité de l’algorithme — un rappel que le delta n’est un signal fiable que sur les fonctions assez faciles pour être résolues (cf MGS-10 sur Rastrigin).
C’est l’enseignement honnête : les features de paysage sont une heuristique, pas un oracle. Elles excellent à écarter les catastrophes évidentes (éviter WOA sur Ackley) et orientent vers les optimiseurs robustes (DE/BBPSO), mais elles manquent la géométrie directionnelle (vallée courbe) : un FDC bas signifie tantôt « multimodal » (Rastrigin) tantôt « courbé » (Rosenbrock), et la feature seule ne distingue pas les deux. Les approches modernes (apprentissage de méta-caractéristiques sur un grand jeu de paysages, features directionnelles, coûts d’évaluation adaptatifs) poussent plus loin — c’est l’objet de l’exercice 4.
11. Synthèse — du sélecteur à l’hyper-heuristique
Le sélecteur de Rice que nous avons construit est une hyper-heuristique de sélection : il ne résout pas le problème lui-même, il choisit quel solveur appliquer. C’est l’aboutissement naturel de la Partie 4 :
Notebook
Apport
MGS-1..9
construire et comprendre les métaheuristiques individuelles
MGS-10
un portfolio mesuré de 8 optimiseurs (le banc center-bias)
MGS-11..14
la synergie : comment les combiner (îles, rotations, paysage)
MGS-15
caractériser un paysage (FDC, autocorrélation, neutralité)
MGS-16
décider : features → portfolio, le sélecteur de Rice
La boucle est bouclée : on est parti de métaheuristiques isolées, on les a mesurées (portfolio), on a appris à décrire les problèmes (paysage), et l’on sait désormais faire correspondre les deux. Le No-Free-Lunch n’est pas une condamnation : c’est l’invitation à raisonner sur le problème avant de lancer l’algorithme.
12. Exercices
Stubs à compléter. Le notebook s’exécute de bout en bout même exercices non résolus (convention C.1 : pas de raise/assert False/1/0).
Exercice 1 — Un paysage à évolution neutre
Les benchmarks continus ont une neutralité quasi nulle. Construisez un IFitnessartificiellement neutre (par ex. quantifier la fitness de Rastrigin par paliers) et montrez que NeutralRatio grimpe. Que devient la recommandation du sélecteur ?
// Exercice 1 -- À COMPLÉTER// Indice : IFitness dont Evaluate arrondit/quantifie la fitness par paliers (Math.Floor),// créant des plateaux neutres. Mesurez NeutralRatio avant/après quantification.publicclass QuantizedRastrigin : IFitness{publicdoubleEvaluate(IChromosome chromosome){ Console.WriteLine("Exercice 1 à compléter : implémentez une Rastrigin quantifiée par paliers.");return0.0;// TODO étudiant}}// var rep = Measure(new QuantizedRastrigin(), dim);// Console.WriteLine(rep);
Exercice 2 — Un sélecteur fondé sur le coût d’évaluation
Jusqu’ici toutes les fonctions coûtent la même chose à évaluer. En pratique, une évaluation peut prendre des secondes (simulation physique). Ajoutez un coût cost au LandscapeReport et modifiez Select pour qu’un paysage cher favorise les optimiseurs économes (BBPSO, recherche aléatoire) sur les gourmands (GA à grande population).
// Exercice 2 -- À COMPLÉTER// Indice : étendez le record LandscapeReport d'un champ Cost (en secondes/évaluations),// puis ajoutez une branche dans Select : si Cost > seuil, préférer BBPSO/Random (peu d'évaluations).Console.WriteLine("Exercice 2 à compléter : intégrez le coût d'évaluation dans le sélecteur.");
Exercice 2 à compléter : intégrez le coût d'évaluation dans le sélecteur.
Exercice 3 — Schwefel et la limite du FDC
La fonction de Schwefel a son optimum loin de l’origine (et KnownFunctionsBounds le reflète : borne [−500, 500]). Or SampleLandscape mesure la distance à l’origine — ce qui fausse le FDC. Exécutez le sélecteur sur Schwefel, comparez à l’oracle, et expliquez pourquoi le FDC devient non-informatif. Comment corriger le calcul de distance ?
// Exercice 3 -- À COMPLÉTER// Indice : SampleLandscape suppose l'optimum à l'origine (DistToOptimum = ||x||).// Schwefel rompt cette hypothèse. Testez le sélecteur vs l'oracle sur SchwefelFitness,// puis proposez une correction (distance au vrai optimum, ou FDC non-radial).Console.WriteLine("Exercice 3 à compléter : diagnostiquez le FDC trompeur sur Schwefel.");
Exercice 3 à compléter : diagnostiquez le FDC trompeur sur Schwefel.
Exercice 4 — Vers l’apprentissage : un sélecteur appris
Notre sélecteur est une expertise encodée à la main. Générez un jeu d’entraînement : N paysages aléatoires (combinaisons linéaires de Sphere/Rastrigin/Ackley), pour chacun ses features + le meilleur optimiseur mesuré (oracle). Puis remplacez la règle Select par un simple classifieur (k-NN ou arbre de décision) appris sur ces N exemples. Le sélecteur appris bat-il la règle manuelle sur de nouveaux paysages ?
// Exercice 4 -- À COMPLÉTER// Indice : boucle sur N combinaisons pondérées (a*Sphere + b*Rastrigin + c*Ackley),// mesurez (features, bestOpt) pour chacune, puis implémentez un k-NN sur les features.Console.WriteLine("Exercice 4 à compléter : construisez un sélecteur appris (k-NN sur les features).");
Exercice 4 à compléter : construisez un sélecteur appris (k-NN sur les features).
Limites honnêtes : (1) nos features sont statiques et radiales (FDC suppose l’optimum à l’origine) — elles ratent les géométries directionnelles (Rosenbrock, Schwefel) ; (2) le sélecteur est heuristique, non appris ; (3) le coût d’évaluation (critique en simulation) n’est pas modélisé ; (4) la généralisation à des familles vraiment étrangères n’est pas garantie (generalization gap).
Pour aller plus loin : - Sélection apprise : Smith-Miles (2008), Towards the provision of information for the algorithm sélection problem ; Kerschke et al. (2019), Automated Algorithm Sélection. - Paysages dynamiques : caractéristiques évoluant dans le temps (cf. MGS-11 îles, MGS-14 synergie). - Hyper-heuristiques de génération : au lieu de sélectionner, générer un nouvel optimiseur composé (cf. MGS-5 métaheuristiques composées).
Références : Wolpert, D. H. & Macready, W. G. (1997), No free lunch theorems for optimization, IEEE Trans. Evolutionary Computation 1(1) ; Rice, J. R. (1976), The Algorithm Sélection Problem, Advances in Computers 15 ; Weinberger, E. (1990), Correlated and uncorrelated fitness landscapes and how to tell the différence, Biological Cybernetics 63(5) ; Jones, T. & Forrest, S. (1995), Fitness Distance Correlation as a Measure of Problem Difficulty for Genetic Algorithms, ICGA.