You are on page 1of 9

Chaines de Markov et Recuit simulé

Matthieu Baudry & Emmanuel Zenou, 2021

L’objectif de ce bureau d’étude est de comprendre comment paramétrer un recuit simulé afin de
trouver une solution globale à un problème d’optimisation. Dans une première partie, vous serez
guidés pas à pas pour coder et paramétrer le recuit. Et dans la seconde partie, vous serez en autonomie
devant un problème d’optimisation appliqué à l’image.

Partie 1 – Exemple d’optimisation par recuit simulé (/12 pts)


1- Enoncé
1.1 – Enoncé du problème

Le projet consiste à résoudre un problème d'optimisation combinatoire proche d'un problème réel. On
veut tester un ensemble de n = 100 composants montés sur un produit. À chaque composant i est
associé un test. Mais le test i peut aussi permettre de tester d'autres composants. Le problème peut
se poser sous les deux formes suivantes :

- étant donné un nombre nt < 100, sélectionner l'ensemble des nt tests les plus performants
possibles en termes du nombre de composants vérifiés. On prendra 𝑛𝑡 = 10 ;
- sélectionner l’ensemble de tests minima permettant de tester tous les composants.

On étudiera ici le premier problème. Le but est de mettre en œuvre l’algorithme du recuit simulé afin
de trouver le jeu de 𝑛𝑡 tests le plus performant.

1.2 – Génération aléatoire d’un espace

Le problème est défini par une matrice binaire 𝐴 = (𝑎𝑖𝑗) avec 𝑎𝑖𝑗 = 1 si le composant i peut être
testé par le test j, et 0 sinon. On a 𝑎𝑖𝑖 = 1. Pour générer les termes non diagonaux de la matrice A, on
les tire au hasard avec la probabilité 𝑝 = 0,04 d'être égaux à 1 indépendamment les uns des autres.
Voici une vue descriptive de la matrice A :

Le nombre de composants testés par le test j est la somme des termes de la colonne j de la matrice A.
C'est au final une variable aléatoire de moyenne 5 et d'écart type proche de 0,2.

Ainsi, si les tests étaient parfaitement complémentaires, avec un jeu de 10 tests, on pourrait tester
plus de cinquante composants et avec une vingtaine de tests, on devrait pouvoir tout tester. Il faut
choisir soigneusement le jeu de tests le plus complémentaire possible.
 Question 1. Générez une matrice A.

Vous utiliserez pour cela la fonction suivante :


function A=Generateur(n,p)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Cette fonction génère un problème de test en générant %
% une matrice binaire carrée de taille n dont les termes %
% diagonaux sont égaux à 1 et dont les termes rectangle %
% sont aléatoires, indépendants et égaux à 1 avec la %
% probabilité p. %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
A_1 = eye(n);
A_2 = rand(n,n);
A_3 = (1-p)*ones(n);
A = max(A_1,A_3<A_2);

1.3 – Génération aléatoire d’un jeu de tests

La fonction ci-après permet de générer aléatoirement un jeu de 𝑛𝑡 tests et de mesurer la performance


de ce jeu. Le vecteur X contient des booléens qui indiquent si le test j est choisi ou non, tandis que le
vecteur 𝑋1 contient la liste des tests choisis, et 𝑋0 contient la liste des tests non choisis :

function [X, X_1, X_0, N]=Init_alea(A,n_t);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% function [X, X_1, X_0, N]=Init_alea(A,n_t)
%
% Cette fonction choisit aléatoirement un ensemble de n_t tests sous
% forme d'un vecteur binaire (n,1) à partir de la matrice d'affectation
% A et de deux vecteurs d'entiers indiquant les numéros d'ordre des
% tests sélectionnés et des tests non sélectionnés. Enfin la performance N
% est renvoyée
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[n p]=size(A);
X=zeros(n,1);
I=randperm(n);
for j=0:n_t-1,
X(I(n-j))=1;
end;
X_0=I(1:n-n_t);
X_1=I((n-n_t+1):n);
N=sum(min(A*X,1));

2 – Modélisation
2.1 – Formalisation du problème
D'un point de vue mathématique, nous avons vu en cours que l'objectif d'un recuit simulé est de
chercher le minimum absolu 𝑥 ∗ d'une fonction 𝑈 appelée énergie dans un espace E donné :
𝑥 ∗ = min 𝑈(𝑥)
𝑥∈𝐸
Cette recherche de minimum se fait le long d'une trajectoire modélisée par une chaîne de Markov. À
chaque état est associé un graphe G définissant ainsi la relation de voisinage, puis la notion de
minimum local autour d'un état 𝑦 :
𝑥 ∗𝑦 = min 𝑈(𝑥)
𝑥∈𝑉(𝑦)

2.2 – Modélisation de la dynamique de Metropolis


Maintenant que la formalisation est posée, il faut préparer la dynamique de Metropolis en modélisant
notre problème, c'est-à-dire en répondant aux trois questions suivantes :

 Question 2. Définir ce qu’est un état dans ce problème ainsi que son voisinage. Définir
également l’énergie du problème (qu’on cherchera ici à maximiser). Quelle variable du
code représente cette énergie ?

Un ensemble de tests est représenté par un vecteur binaire X dont les composantes identifient les tests
de l'ensemble. Pratiquement, l'opérateur de sélection maintient l'ensemble de tests courant et son
complémentaire et opère une sélection aléatoire d'un élément dans l'ensemble de tests courant, d'un
élément dans son complémentaire et les échange. L'opérateur d'évaluation évalue alors la différence
entre le nombre de composants testés dans les deux configurations. L'initialisation est opérée par le
tirage aléatoire d'un ensemble de 𝑛𝑡 tests ou par la sélection des dix tests individuellement les plus
performants.

Voici programme en Matlab un algorithme donnant la transition de Metropolis en fonction de la


température T :

function [Xout, Xout_1, Xout_0,Nout]


= Metropolis(n, n_t, A, T,Xin, Xin_1, Xin_0, Nin)

X = Xin;
Xout_1 = Xin_1;
Xout_0 = Xin_0;

% Définition d'un voisin :


i_1 = ceil(n_t*rand);
i_0 = ceil((n-n_t)*rand);
X(Xin_1(i_1)) = 0 ;
X(Xin_0(i_0)) = 1 ;

% Mesure de performance :
N = sum(min(A*X,1));
if N>Nin+T*log(rand)
Xout=X;
Xout_1(i_1) = Xin_0(i_0) ;
Xout_0(i_0) = Xin_1(i_1) ;
Nout=N;
else
Xout=Xin;
Nout=Nin;
end
 Question 3. Implémenter cet algorithme et démontrer l’écriture du test
if N > Nin+T*log(rand). Comment aurait-il fallu réécrire ce test si on avait cherché à
minimiser l’énergie ?

 Question 4. Pour une condition initiale donnée, observer les niveaux d'énergie d'une
trajectoire au cours du temps à différentes températures (T = 0, T = 0.1, T = 0.5, etc. ). À
quoi correspond cette dynamique pour T = 0 ? Et pour une température élevée ?
Renouveler l'expérience avec plusieurs conditions initiales.

3 – Recuit simulé

Pour mettre en œuvre l'algorithme de recuit simulé, maintenant que nous avons défini la notion d’état,
de voisinage, d’énergie et de dynamique de Metropolis, il faut déterminer les paramètres suivants :

1. les températures initiales et finales qui borneront le recuit simulé ;

2. la longueur optimale des plateaux pour les chaînes de Markov, au-delà de laquelle il est
inutile de continuer tant les propriétés stochastiques ne varient pas.

Ces deux paramètres s'obtiennent respectivement en étudiant les distributions limites (loi de Gibbs)
en fonction de plusieurs températures d’une part, et les convergences vers les distributions limites
d'autre part.

3.1 - Loi de Gibbs


On fait maintenant fonctionner l'algorithme de Metropolis à différentes températures pour avoir une
idée de la convergence vers les lois de Gibbs (ne pas oublier d'écarter les premières itérations du
régime transitoire). Bien entendu, on ne relève pas les fréquences de visite de chaque état (ce qui
serait impossible) mais de chaque énergie (la convergence sur les états entraîne la convergence sur les
énergies).

On aura ainsi une idée du temps de convergence vers la loi stationnaire qui permettra de régler le
schéma de recuit et de sélectionner les températures pertinentes pour l'algorithme.

function proba = Gibbs(n,p,n_t,A,T,N_hist,t_iter,n_iter)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% function proba=Gibbs(n,p,n_t,A,T,N_hist,t_iter,n_iter)
%
% Objet de la fonction :
% ++++++++++++++++++++++
% Cette fonction retourne un histogramme de fréquences de visites
% pour n_iter itérations de la dynamique de Metropolis sur n_iter
% pas de temps après avoir écarté autant de transitoires.
% Les centres de classe sont donnés par n_hist.
%
% Output :
% ++++++++
% proba vecteur des fréquences de l'histogramme des niveaux de la
% fonction coût
%
% Input :
% ++++++
% n entier (100 à 200) taille du problème
% p probabilité pour un composant d'être couvert par un test
% n_t nombre de tests admissibles
% A matrice d'affectation générée par Générateur
% T réel positif, température
% N_hist vecteur ligne des centres de classes de l'histogramme
% t_iter longueur de simulation d'une chaîne de Markov
% n_iter nombre de chaînes de Markov lancées pendant l'exécution
%
% Fonctions appelées :
% ++++++++++++++++++++
% Init_alea
% Metropolis
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

NN=zeros(1,t_iter); % trajectoire des performances


n_classes=length(N_hist); % nombre de classes de l'histogramme
proba=zeros(1,n_classes); % fréquence de visite des classes de
l'histogramme
moy=1/(n_iter*t_iter); % normalisation des fréquences

for ii=1:n_iter
%transitoire
[Xin, Xin_1, Xin_0, NN(1)]=Init_alea(A,n_t); % initialisation de
l'état
for t=2:t_iter
[Xout, Xout_1, Xout_0,NN(t)] = ...
Metropolis(n, n_t, A, T,Xin, Xin_1, Xin_0, NN(t-1));
Xin=Xout;
Xin_1=Xout_1;
Xin_0=Xout_0;
end
NN(1)=NN(t_iter);

% début de la trajectoire enregistrée


for t=2:t_iter
[Xout, Xout_1, Xout_0,NN(t)] = ...
Metropolis(n, n_t, A, T,Xin, Xin_1, Xin_0, NN(t-1));
Xin=Xout;
Xin_1=Xout_1;
Xin_0=Xout_0;
end
n_freq=hist(NN,N_hist);
proba=proba+moy*n_freq;
end

plot(N_hist,proba,'+-')
title(['Histogramme de Gibbs à température ',num2str(T),' : n=',...
int2str(n),',nt=',int2str(n_t),', p=',num2str(p)]);

 Question 5. Déterminer les distribution de Gibbs pour différentes températures : T =


[50, 10, 5, 1, 0.5, 0.1, 0.05, 0.01, 0].
 Question 6. En déduire les valeurs initiales et finales nécessaires au recuit.

3.2 – Convergence en loi


L'idée maintenant est d'évaluer la décroissance logarithmique (𝑇𝑛 +1 = 𝛼 ∗ 𝑇𝑛), soit en cherchant la
bonne valeur de décroissance 𝛼 entre deux températures successives, soit en cherchant la bonne
longueur de plateau (avec 𝛼 fixé). L'idée est de regarder l'évolution de la loi le long de la chaîne, et
d'évaluer le temps nécessaire pour assurer toute convergence.
Pour cela, on regardera la distribution au cours du temps de la chaîne de Markov. On s'assurera que la
loi stationnaire est atteinte en comparant les probabilités obtenues à partir d'états initiaux différents.

 Question 7. En regardant l’évolution des distributions en fonction du nombre


d’itérations de la dynamique de Metropolis, donner un ordre de grandeur du nombre
d’itérations nécessaires pour converger vers la loi de Gibbs (pour T=0, 0.5 et 1).

De façon plus précise, pour quantifier la distance entre les lois de probabilité sur l'ensemble des
énergies, on quantifie celui-ci et on associe à une probabilité un vecteur stochastique p = (pi). On a
ensuite le choix entre différentes distances, comme par exemple :

𝑑1 (𝑝,𝑞 ) = ∑|𝑝𝑖 − 𝑞 𝑖 |
𝑖

𝑑2 (𝑝, 𝑞 ) = √∑(𝑝𝑖 − 𝑞 𝑖 )2
𝑖

 Question 8. Etudier les convergences en loi pour les deux normes et pour différentes
températures. Donner une valeur plus précise de longueur d’un plateau qui convienne
à toutes les températures.

3.3 – Mise en œuvre du recuit simulé


Maintenant que les trois paramètres suivants sont connus :

1. la température initiale Ti,


2. la température finale Tf,
3. et la longueur de pallier L, que l'on supposera constante

Il est possible de mettre en œuvre le recuit simulé.

 Question 9. Mettre en œuvre le recuit simulé avec un algorithme à décroissance


géométrique (avec α = 𝟎. 𝟗𝟓) de la température et plateaux pour obtenir la solution
du problème.
Remarque : la loi finale n'est pas une loi de Gibbs! En effet, dans le cas contraire, si la chaîne était
ergodique, on devrait obtenir la même distribution qu'en utilisant la température finale,
indépendamment du chemin suivi. . . Or le graphe associé n'est pas homogène (il dépend du temps),
donc on est dans un cas général bien plus complexe que la simple convergence vers la loi de Gibbs à
température donnée.

Partie 2 – Application à l’image (/8 pts)

Dans cette partie, l’idée est de faire fonctionner un recuit simulé pour compter le nombre de cellules
dans une image (bloodCells.jpg) :

Dans un premier temps il faudra traiter l’image pour la binariser.

 Question 10. Binariser l’image BloodCells.jpg, c’est-à-dire donner un procédé pour


créer un masque qui contient des 1 là où il y a une cellule, et des 0 sinon.
Ensuite, il faut définir une stratégie : un état, son voisinage et une énergie.

Par exemple, un état peut être un vecteur qui contient une liste de positions (u,v) des cellules avec
un rayon R estimé et fixé. Un voisin peut donc être une modification (δ𝑢, δv) de la position d’une
cellule prise aléatoirement. Un voisin peut également être une addition ou suppression d’une cellule.
On peut également se dire que le rayon moyen étant inconnu, il fait partie des paramètres à
optimiser, et un voisin pourrait être une modification δ𝑅 du rayon. Enfin, nous pouvons penser à une
représentation dans laquelle le rayon est considéré comme dépendant de la cellule, et ainsi chaque
cellule aurait sa propre valeur de rayon.
Pour ce qui est de l’énergie, il est possible de considérer une sorte de score entre l’image des cellules
et une image qui représente le vecteur d’état. Par exemple, à partir du vecteur d’état, on peut créer
une image binaire qui est noire là où il n’y a pas de cellule, et vaut 1 là où il y a une cellule. Ensuite,
une comparaison avec le masque binaire de l’image réelle permettra de sortir un score.

Exemple :

En considérant l’image binarisée suivante (qui symbolise notre image de cellules):

Et dans l’hypothèse d’un vecteur d’état qui contient une seule cellule de rayon R fixé, et de position
(𝑥 1,𝑦1 ) , que l’on peut modéliser sous forme d’image binaire :

𝑦1

𝑥1

On peut définir l’énergie comme le nombre de pixels qui font partie de l’intersection des deux
images (la partie rouge pâle de l’image suivante), minoré par le nombre de ceux qui sont dans l’union
mais pas dans l’intersection (les pixels blancs et rouge foncés) :
Avec cette définition de l’énergie, on cherchera à la maximiser afin d’avoir le plus de recouvrement
entre les disques rouges (du vecteur d’état) et les disques blancs (de la vraie image).

Il existe ainsi de nombreuses façons de résoudre le problème, plus ou moins complexes mais aussi
plus ou moins précises.

Dans ce problème, les cellules ont à peu près toutes la même taille, donc on travaillera avec un rayon
unique.

 Question 11. Estimer manuellement une valeur du rayon.


 Question 12. Définir un état et la notion de voisinage autour de cet état
 Question 13. Définir mathématiquement une énergie à maximiser
 Question 14. Mettre en œuvre une dynamique de Metropolis et vérifier visuellement le
comportement pour différentes températures. Définir ainsi les températures min et
max, et une longueur de plateau.
 Question 15. Lancer le recuit simulé et donner le nombre de cellules trouvées. Donner
quelques illustrations intermédiaires.

Remarque :

La très pédagogique chaîne YouTube ScienceEtonnante de David Louapre contient une vidéo
dont le sujet est l’utilisation du recuit pour déchiffrer de façon quasi certaine des messages
chiffrés par substitution :

https://scienceetonnante.com/2021/04/23/mcmc-code/

You might also like