• Aucun résultat trouvé

Utilisation d’un algorithme genetique pour la génération de procédésprocédés

Generation de procédés basée sur un algorithme génétique multi objectif

5.4 Utilisation d’un algorithme genetique pour la génération de procédésprocédés

L’intérêt d’utiliser un GA pour générer des procédés provient de leur habilité à optimiser une population de solutions potentielles vers les objectifs de génération désirés. En donnant à l’algorithme un moyen de faire évoluer un procédé et en donnant une fonction d’évaluation des objectifs, le GA est capable de faire évoluer une population de candidats vers une solution potentielle à travers le principe de sélection naturelle.

La figure5.5montre comment le GA est utilisé pour générer un procédé et est expliquée dans la suite en reprenant les étapes décrites précédemment pour appliquer un GA. Un chromosome correspond à un procédé quand un élément de celui-ci (c’est-à-dire des noeuds et arcs) représente ses gènes.

Figure 5.5 – Vue globale de l’utilisation d’un GA pour la génération d’un procédé [156] Genèse. Afin de configurer la population initiale, certaines informations sont requises :

– La taille de la population, qui correspond au nombre maximal de solutions possibles. Une taille importante augmente les chances de converger plus rapidement vers les objectifs, au coût d’un temps de calcul supérieur pour faire évoluer la population.

– Le procédé initial qui évoluera pendant la phase d’évolution. Par défaut, le procédé cor-respond à un simple procédé avec un noeud initial (ex. InitialNode) et un noeud final (ex. ActivityFinalNode). Ce choix est naturel du fait que tous les procédés possèdent un début et une fin. Par ailleurs, il est aussi possible d’utiliser un procédé initial défini par l’utilisateur. Dans ce cas, les procédés générés seront une dérivation de ce procédé. Ainsi, ce procédé initial est copié dans toute la population initiale.

Evaluation. La fonction d’évaluation évalue une solution par rapport aux objectifs définis. En partant du principe que p est une solution potentielle, Csest la taille désirée du procédé, Cmest la marge acceptée sur la taille Cs, Ce est l’ensemble qui contient le nombre désiré de chacun des éléments du méta-modèle, Cw est l’ensemble qui contient le nombre désiré de workflow patterns,

Cc est l’ensemble des contraintes syntaxiques, et Ws, We, Ww, Wc sont les poids respectifs à chacun de ces objectifs. Soit W la somme de tous les poids. Soit hold(candidate, objective) une fonction qui retourne 1 si l’objectif (objective) est atteint par le candidat (candidate), et 0 dans le cas contraire. Soit size(candidate) une fonction qui retourne la taille (en terme de nombre de noeuds et arcs) d’un candidat (candidate). Soit margin(x) une fonction de seuil utilisé pour connaître les tailles de procédé acceptées selon la marge Cm. La fonction fitness(candidate) retourne un réel entre [0, 1] qui reflète la qualité du candidat (une valeur élevée veut dire que la solution est meilleure) :

margin(x) = Y ] [ 0 iffx 6 Cm 1 iffx > Cm fitness(p) = A 1 1 + margin(|size(p) ≠ Cs|) B úWWs + Q a ÿ wœCw hold(p, w) card(Cw) R b úWw W

+ Q aÿ eœCe hold(p, e) card(Ce) R b ú We W + Q aÿ cœCc hold(p, c) card(Cc) R b ú Wc W (5.1)

Soit ” un nombre réel entre [0, 1] représentants le seuil d’acceptation d’un candidat. Soit

f itenough(candidate) une fonction qui retourne un booléen déterminant si la solution est consi-dérée suffisamment correcte (c’est-à-dire si les objectifs sont atteints) :

fitenough(p) = 1 ≠ fitness(p) < ” (5.2)

Il est important de noter qu’une valeur faible affectée à ” implique plus de rigidité afin qu’une solution potentielle p soit jugée suffisamment correcte. Le principal intérêt d’utiliser des poids est que s’il est impossible de remplir tous les objectifs, il est toujours possible de prioriser les objectifs les plus importants en leur associant un poids plus grand. Les objectifs peuvent être vus comme des buts moue qui doivent être atteint le mieux possible. Plus des objectifs sont ajoutés sur les buts de la génération, plus l’ensemble des solutions potentielles est restreint. Par exemple, il existe moins de solutions possibles correspondant à “générer un procédé de 10 noeuds dont 3 de branchement conditionnel” que simplement “générer un procédé de 10 noeuds”. De plus, certain objectifs peuvent être mutuellement exclusifs : “générer un procédé ne contenant aucun noeud de branchement parallèle, mais contenant le workflow pattern parallel split”. En effet, un procédé contenant le workflow pattern “parallel split” contient forcément un noeud de branchement parallèle. Ainsi dans ce genre de cas, il est impossible de satisfaire tous les objectifs. Survie du plus apte. La sélection doit favoriser les candidats jugés bons par rapport à ceux jugés plus faibles. Cependant, il n’y a pas de règles générales, aucune stratégie n’est la meilleure pour tous les problèmes. Nous utilisons la technique de sélection proportionnelle aux scores la plus couramment utilisée, appelée “Roulette Wheel Selection” (RWS) [15]. Conceptuellement, chacun des membres de la population se voit attribué une section sur une roulette imaginaire. Une proportion de la roue est attribuée à chacun des candidats en fonction de leurs scores. À l’inverse d’une roue réelle, les sections sont de différentes tailles, proportionnellement à chacune, de manière à ce que les candidats avec un score élevé se voient attribuer une plus grosse portion de la roue. La roue est ainsi tournée, et le candidat associé à la section sélectionnée est choisi. La roue est tournée autant de fois que nécessaire pour sélectionner l’ensemble des parents de la génération suivante. Afin de s’assurer que certains candidats prometteurs ne puissent être perdus lors du passage à la génération suivante, nous utilisons le principe d’élitisme. Ce principe implique qu’une portion des meilleurs candidats est directement copiée vers la prochaine génération. Evolution. Pour chacune des évolutions, certaines opérations génétiques sont appliquées sur chacun des candidats de la population. Nous utilisons seulement le principe de mutation. Dans notre cas, cette mutation correspond à l’application aléatoire d’un change pattern. Afin de générer des procédés réalistes, il est nécessaire de pouvoir spécifier une probabilité sur la chance d’appliquer un change pattern donné sur un candidat. En effet, lorsqu’un modélisateur construit un procédé, il y a plus de chance qu’il effectue un serialInsert plutôt qu’un conditionalInsert. Ainsi, la fonction d’évolution a besoin de prendre en compte une probabilité définie par l’utilisateur pour chacun des change patterns. Il est bien évidemment possible de donner des probabilités par défaut à chacun des change patterns en étudiant des procédés de la littérature ou d’un domaine donné. Cependant, il est intéressant de pouvoir modifier ces valeurs. Par exemple, augmenter la probabilité d’application du change pattern parallelInsert augmentera les chances de générer des procédés massivement parallèles tout en réduisant les chances de générer des procédés plutôt séquentiels. Des probabilités bien affinées sur chacun des change patterns permettent de générer des procédés réalistes en simulant ce qu’aurait fait réellement un modélisateur. Ainsi, la mutation

correspond à appliquer un change pattern selon sa probabilité d’être choisie. La population entière évolue en parallèle.

Iteration. La génération termine quand une condition est atteinte. Nous proposons plusieurs solutions (non exclusives) pour terminer la génération :

1. Arret quand une solution est trouvée (la fonction fitenough renvoie vraie) ; 2. Arret après x itérations ;

3. Arret après x stagnation du meilleur candidat (aucune amélioration du score après plusieurs itérations) ;

4. Arret après x secondes (permets de spécifier un temps d’expiration s’assurant que l’algo-rithme ne s’exécute pas indéfiniment).

Si plusieurs conditions de terminaison sont spécifiées, l’évolution s’arrête dès que l’une d’entre elles est atteinte. Utiliser simplement la condition n°1 peut impliquer que l’algorithme s’exécute indéfiniment. Par exemple, en cas d’objectifs mutuellement exclusifs, il est possible que le score des candidats soit toujours insuffisant pour que la fonction fitenough renvoie vraie. Ainsi, les conditions n°2, 3 et 4 donnent des conditions qui finiront forcément au bout d’un certain temps à être remplies. Quand l’évolution se termine, l’algorithme renvoie le candidat dont le score est le plus élevé. Ainsi, le candidat est la solution, c’est-à-dire le procédé généré.