• Aucun résultat trouvé

Recherche de solutions avec les AG

Chaîne logistique

3.4 Méta-heuristiques

3.4.3 Recherche de solutions avec les AG

Nous décrivons dans cette section tous les éléments dont on a besoin pour l’algorithme génétique que nous proposons. Nous présentons d’abord le codage des chromosomes, les opérateurs de croisements et de mutation, et le schéma général de l’algorithme.

3.4.3.1 Le Codage

Le codage de la solution est un facteur très important dans l’efficacité d’un algorithme génétique, c’est la façon avec laquelle on représente un chromosome. Une solution du problème est simple : il s’agit de permutations de travaux, en voici un exemple :

3 4 1 8 9 2 10 7 6 5

Néanmoins, pour implémenter les opérateurs que nous proposons, il nous faut d’autres informations que nous conservons également dans le chromosome. Ces informations sont les dates de début d’exécution des jobs sur la première machine, et sur la dernière machine (car nous nous intéressons à des problèmes de juste à temps où les pénalités d’avance-retard sont associées à la première et à la dernière opération).

3.4.3.2 Les opérateurs

Nous présentons ici les opérateurs binaires (croisements) et unaires (mutations) que nous avons conçu ou adapté spécialement pour le problème étudié.

3.4.3.2.1 Les croisements

Nous avons développé des croisements basés sur un tri complet, ou partiel, et procédant par recopie de certaines parties des parents, le tout en utilisant les informations sur les dates de début d’exécution des jobs sur la première et la dernière machine selon l’algorithme suivant :

Algorithme Début

i. Nous disposons des parents P1 et P2.

ii. Générer un point de coupure aléatoirement dans le parent P1. Soit L ce point. iii. Copier dans le fils F1 la partie de 1 à L (partie gauche) de P1.

iv. Dans la deuxième partie du fils, les jobs non encore attribués sont mis dans l’ordre croissant de 2 2 1 i i λ λ + tel que 1 i λ (resp. 2 i

λ ) est la date de début d’exécution du job sur la première machine dans le parent P1 (resp. P2).

Fin

Il est à noter que les k i

λ correspondent à la solution du Pert Coût pour les individus faisables et aux dates au plus tôt sur les dates de début impératives pour les individus non faisables.

En inversant la copie (copier la partie droite au lieu de la partie gauche) on obtient un autre enfant. En intégrant le classement aussi à la partie copiée, on obtient un autre enfant. En inversant les rôles de P1 et P2 on obtient un autre fils. Finalement, si on ne fait pas de copie, et qu’on fasse le tri sur tout le chromosome, on obtient un autre type d’enfants. On peut

prendre les λi de la première ou de la dernière machine. En définitif, on a 18 façons de générer des enfants.

La figure suivante montre la construction des enfants à partir des parents P1 et P2. P1 P2 2 2 1 i i λ λ + P1 2 2 1 i i λ λ + P2 2 2 1 i i λ λ +

Figure 3.24 les croisements basés sur les dates d’exécutions.

Une autre manière de faire un croisement spécifique à notre problème de juste à temps qui n’est applicable que si les deux parents sont faisables, est de considérer le coût de chaque job (dans le parent considéré) à la position à la quelle il est affecté. La figure fig.3.25 décrit l’algorithme du croisement basé sur les coûts des jobs. Le principe est simple : on a deux parents, on parcourt le parent principal (soit le premier parent sélectionné) de gauche à droite, et on compare le coût de chaque job dans chacun des deux parents. Le job est affecté dans le fils, à la position dans le père ou la mère qui a le moindre coût (somme d’avance et retard par rapport aux dates souhaitées de livraison et de disponibilité). Si cette position est déjà affectée, alors on l’affecte à la première position libre qui succède. Le deuxième enfant est obtenu en se basant cette fois ci sur les positions, et non sur les jobs. On parcourt les deux parents de gauche à droite, et pour chaque position est affecté le job dans le père ou la mère qui a le moindre coût. Si pour une position donnée, les deux jobs correspondant sont déjà affectés, alors on y affecte le premier job non affecté.

Algorithme Job Based Crossover Début

 Soient P1 et P2 les deux parents de longueur N.

Pour i=1 à N Faire

 Soit J1 l’indice du job à la position i dans P1.

 Chercher la position de J1 dans P2. Soit j cette position.

Si (les positions i et j dans le fils F1 ne sont pas déjà remplies) Alors

Si coût (P1, J1)< coût (P2, J1) Alors

 Le job J1 est affecté à la position i dans F1.

Sinon J1 est affecté à la position j dans F1. Sinon

Si la position i est remplie alors affecter J1 à la position j. Si la position j est remplie alors affecter J1 à la position i. Sinon

Affecter J1 à la première position libre après i ou j.

FinPour

Fin

Figure 3.25. Algorithme du croisement basé sur les coûts des jobs. L’algorithme du croisement basé sur les positions est donné par la figure suivante :

Algorithme Position Based Crossover Début

 Soient P1 et P2 les deux parents de longueur N.

Pour i=1 à N Faire

 Soit J1, J2 les indices des jobs à la position i dans P1 et dans P2.  Si coût(P1, J1)< coût(P2, J2)Alors

Si J1 non encore affecté Alors

 Affecter J1 à la position i dans le fils F1.

Sinon

 Si J2 non encore affecté Alors

Affecter J2 à la position i dans le fils F1. Sinon

Si J2 non encore affecté Alors

 Affecter J2 à la position i dans le fils F1.

Sinon

 Si J1 non encore affecté Alors

Affecter J1 à la position i dans le fils F1.

FinPour

FIN

Figure 3.26 Algorithme du croisement basé sur les positons.

3.4.3.2.2 Les mutations

Nous avons utilisé la mutation simple basé sur l’échange de deux jobs tirés aléatoirement, ainsi que deux nouvelles mutations dans lesquelles nous avons essayé d’utiliser les propriétés du problème de juste à temps étudié. La première mutation consiste à avancer d’une position le job avec le plus grand retard, la deuxième consiste à reculer d’une position le job avec la plus grande avance.

En outre, pour les problèmes spécifiques de structure d’ateliers en flowshop de permutation, nous avons adapté la technique dite de blocks de jobs développée par (Nowicki et Smutnicki, 1996). Cette technique a été développée pour le problème de flowshop de permutation avec l’objectif de minimiser le makespan. Elle définissait une nouvelle méthode de recherche par voisinage utilisé dans un algorithme de recherche taboue (pour minimiser la durée totale).

Cette technique se base sur la définition de la notion de blocks de jobs. On commence par rechercher le chemin critique (le plus long chemin) dans le problème modélisé par un graphe potentiel. En utilisant certaines propriétés, les jobs sont regroupés en blocks. La principale utilité de cette méthode est qu’elle définit un ensemble de permutations (un voisinage) qui ne sont pas intéressantes (n’améliore pas le makespan minimum), et de ce fait on oriente la recherche vers un ensemble bien précis, ce qui peut améliorer et accélérer la convergence de l’algorithme de recherche de solutions faisables pour notre application. Les détails sur cette méthode sont présentés dans (Nowicki et Smutnicki, 1996) et aussi dans (Janiak et Portmann, 1998).

3.4.3.3 Schéma Elitiste 3.4.3.3.1 Les paramètres

On doit aussi définir certains paramètres comme la taille de la population, les probabilités de croisement, et de mutation, le nombre de générations maximum, le critère d’arrêt. Pour faire le calibrage de l’algorithme génétique, on se base sur les expériences et on fait un compromis entre temps d’exécution, rapidité de convergence, et qualité de la population.

3.4.3.3.2 Choix des opérateurs

Dans la conception d’un algorithme génétique, il ne faut jamais perdre de vue qu’il n’y a aucun opérateur de croisement, mutation, sélection ou remplacement qui soit meilleur qu’un autre dans tous les cas et pour tous les problèmes. L’expérience montre qu’il faut faire des tests pour choisir les opérateurs adéquats pour un problème donné. C’est ainsi que sur la base des tests effectués nous avons choisis les opérateurs qui semblent les meilleurs parmi ceux testés pour notre problème.

3.4.3.3.3 Schéma

Nous proposons le schéma dit élitiste suivant :

Schéma élitiste Début

Initialisation

 Générer une population initiale P0 de Q individus dont les 2/3 sont faisables.

Evaluation :

 Evaluer la force (fitness) de chaque individu de la population Pk1. Trier la population dans l’ordre décroissant.

Sélection :

 Sélectionner 2 Q× /3 couples d’individus dans la première partie de la population Pk1.

Croisement :

 On applique un opérateur de croisement orienté données à chaque couple d’individus. Si un des enfants est identique à l’un des parents, alors on génère des fils avec l’opérateur 2X.

 On garde et les parents, et les enfants dans la population.

Mutation

 On applique l’opérateur de mutation à chaque individu avec la probabilité pm. L’individu est conservé à l’identique avec la probabilité 1−pm.

 La probabilité de mutation est choisie plutôt petite.

Remplacement :

 On trie la population, et on ne garde que les Q meilleurs individus.

Arrêt :

 Aller à évaluation tant que le nombre de générations à générer n’est pas atteint.

Fin

Figure 3.27 Schéma élitiste.