|
|
Dernière mise à jour : 18 Août 1999
Note : Ce texte est basé en partie sur le mémoire de DEA de Mathématiques de Mamadou Boli Ba (Université de Limoges, Juin 1998). Je remercie M. Ba pour sa collaboration.
De nombreux problèmes reviennent à chercher le minimum ou le maximum d'une fonction de plusieurs variables (un exemple typique est fourni par la régression non linéaire). L'optimisation stochastique a pour but d'approcher cet extrêmum au moyen d'une recherche aléatoire. Sous la forme du recuit simulé, elle permet en théorie de trouver l'extrêmum global de la fonction, alors que la plupart des méthodes classiques (déterministes) se limitent à un extrêmum local.
Nous n'envisagerons ici que le cas de la minimisation (puisque maximiser une fonction F revient à minimiser -F). Nous étudierons successivement :
Soit F(X) une fonction de n variables x1, x2, ..., xn, dont on cherche le minimum (X est le vecteur des variables). Un algorithme de descente aléatoire se présenterait comme suit :
|
Le passage de Xr à X se fait par tirage aléatoire, p. ex. selon une loi normale centrée sur X (Voir le cours sur les nombres aléatoires).
L'inconvénient de cette méthode est qu'elle n'accepte que des diminutions de la fonction. L'algorithme risque ainsi de se trouver bloqué dans un minimum local.
Le recuit simulé (simulated annealing) permet de sortir d'un minimum local (et donc, en théorie, d'atteindre le minimum global) en acceptant, avec une certaine probabilité, une augmentation de la fonction.
Cette technique s'inspire de la thermodynamique. En effet, les systèmes physiques atteignent rapidement leur état d'équilibre (minimum d'énergie) en dépit du nombre immense de configurations que peuvent prendre les particules constituant le système. Au cours de cette transition vers l'équilibre, l'énergie peut localement augmenter.
Or, la probabilité p pour qu'un système physique passe du niveau d'énergie E1 au niveau E2 > E1 est donnée par la loi de Boltzmann :
|
|
|
où k est la constante de Boltzmann et T la température absolue.
La probabilité d'observer une augmentation de l'énergie est donc d'autant plus grande que la température est élevée.
Dans le recuit simulé :
Un algorithme de recuit simulé se présente sous la forme générale suivante :
|
La fonction Accepte(dF, T) se présente ainsi :
|
où Random(0, 1) désigne un nombre aléatoire uniforme sur l'intervalle [0, 1[
Pour implémenter cet algorithme, il nous faut donc :
Au début des itérations, alors qu'on est éloigné du minimum, on choisit une probabilité d'acceptation élevée, p.ex. p = 0,5. On peut alors effectuer un certain nombre de tirages aléatoires et calculer la valeur médiane M des augmentations de la fonction (la médiane est la valeur qui partage une distribution en deux parties égales). La température initiale T0 s'en déduit par :
d'où :
On choisit habituellement une décroissance géométrique :
soit :
|
|
|
On peut arrêter les itérations lorsque la température est devenue inférieure à une fraction donnée de la température initiale, p. ex. Tn < 10-6 T0
Il ne s'agit là que de l'algorithme de base. De nombreuses améliorations sont possibles (voir p.ex. le programme ASA de Lester Ingber).
L'optimisation par le recuit simulé peut être réalisé au moyen de la bibliothèque TP MATH.
L'unité OPTIM.PAS, contenue dans TPMATH1.ZIP, fournit une procédure de recuit simulé, ainsi que quelques méthodes déterministes :
Note : ces deux dernières méthodes seront décrites dans un autre cours.
Le type de la fonction à minimiser est défini comme suit :
type
TFuncNVar = function(X : PVector) : Float;
Remarque : Pour la signification du type PVector, voir le cours sur le calcul matriciel.
Les variables globales suivantes sont utilisées pour contrôler l'algorithme de recuit :
const
SA_Nt : Integer = 50; { Nb d'itérations à chaque température }
SA_Cv : Float = 0.5; { Coef. de variation des nombres aléatoires }
SA_MinSigma : Float = 1.0; { Ecart-type minimal des nombres aléatoires }
SA_SigmaFact : Float = 0.1; { Facteur de réduction global de l'écart-type }
SA_NCycles : Integer = 1; { Nombre de cycles de recuit }
Remarques :
MinSigma + Cv * |xi|
où MinSigma et Cv sont initialisés à SA_MinSigma et SA_Cv, respectivement, et diminués à chaque changement de température, de sorte que leurs valeurs finales soient à SA_SigmaFact de leurs valeurs initiales. Cette diminution progressive de l'écart-type permet de réduire la taille de la portion d'espace explorée à mesure que l'on se rapproche du minimum.
En modifiant la valeur de SA_NCycles, on peut effectuer plusieurs cycles de recuit simulé, en recalculant à chaque fois la température initiale. Ceci permet de relancer l'algorithme s'il s'est arrêté à trop grande distance du minimum.
Les deux variables globales suivantes permettent d'écrire un fichier log qui contiendra le détail des itérations (ceci pour les 4 méthodes d'optimisation) :
const
WriteLogFile : Boolean = False; { Indique si le fichier doit être écrit ou non }
LogFileName : String = 'OPTIM.LOG'; { Nom du fichier }
Le fichier log est réécrit à chaque appel d'une procédure d'optimisation. Dans le cas du recuit simulé, il contient, pour chaque étape de recuit :
La procédure de recuit simulé est définie comme suit :
function SimAnn(Func : TFuncNVar;
X : PVector;
Lbound, Ubound : Integer;
MaxIter : Integer;
T_Ratio : Float;
var F_min : Float) : Integer;
La signification des paramètres est la suivante :
En entrée ------------------------------------------------------------ Func = Fonction à minimiser X = Coordonnées approchées du minimum Lbound = Indice de la première variable Ubound = Indice de la dernière variable MaxIter = Nombre d'étapes de recuit T_Ratio = Rapport de la température finale à la température initiale En sortie ------------------------------------------------------------ X = Coordonnées affinées du minimum F_min = Valeur de la fonction en X
Remarques :
Le générateur de nombres aléatoires est réinitialisé à chaque appel de la fonction. On obtiendra donc des résultats différents à chaque appel. Il est conseillé de lancer plusieurs fois la fonction et de comparer les résultats.
Le facteur de réduction de la température RT est déterminé par les valeurs de MaxIter et T_Ratio selon l'équation (2) :
p. ex. avec MaxIter = 100 et T_Ratio = 10-6 on a :
RT = (10-6)1/100 ~ 0,87
Le programme MINFUNC.PAS, disponible dans TPMATH2.ZIP, permet de tester le recuit simulé, ainsi que les 3 autres algorithmes d'optimisation proposés.
Il y a 10 fonctions tests, codées dans des fichiers à inclure (MINFUNC0.INC à MINFUNC9.INC).
A titre d'exemple, considérons la fonction de deux variables, codée dans MINFUNC9.INC (NB : Pour simplifier, nous avons écrit les variables sous forme x, y au lieu de x1, x2) :
F(x, y) = x2 + y2 - cos(12x) - cos(18y)
Le graphique ci-dessous montre que cette fonction possède de nombreux mimima locaux. Le minimum global se trouve en (0,0), avec F(0,0) = -2.
Figure 1
Graphe de la fonction F(x, y) = x2 + y2 - cos(12x) - cos(18y)
(Graphique réalisé avec Maple)
Nous avons lancé 5 fois le recuit simulé en partant du point (2, -3) avec MaxIter = 50, T_Ratio = 10-8, et toutes les variables globales ayant leurs valeurs par défaut. Nous avons obtenu les résultats suivants :
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
On constate que le recuit simulé donne une bonne approximation du minimum global. A titre de comparaison, les méthodes classiques ont donné les résultats suivants :
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
La méthode du simplexe donne les meilleurs résultats mais reste tout de même "piégée" dans un minimum local.
Bien que le recuit simulé soit souvent présenté comme une méthode d'optimisation réservée aux fonctions à variables discrètes, il peut également fournir de bonnes approximations du minimum global dans le cas d'une fonction à variables continues. Ces approximations peuvent ensuite être affinées par l'une des méthodes classiques d'optimisation locale.