• Aucun résultat trouvé

Notre système de tableau de bord est destiné à être utilisé pour supporter la prise de décision en contexte industriel. À titre de preuve de concept, nous l’avons appliqué au cas réel d’une entreprise forestière canadienne. Nous voulions déterminer si notre système était suffisamment réactif et flexible pour s’adapter aux besoins d’une entreprise. Pour ce faire, le modèle uti- lisé [15] contient approximativement 64000 variables dont près de 2000 sont d’intérêt pour le

décideur.

Le problème résolu par le modèle est l’allocation de blocs de coupes vers des usines [13]. La forêt est divisée en 50 blocs de coupe qui alimentent 5 scieries. Le transport vers les usines peut s’effectuer soit à l’aide de camions routiers ou par des camions forestiers hors normes. Les variables de décisions concernent la quantité de bois récolté dans chaque bloc, le choix de longueur de coupe, l’allocation des différents produits aux usines et le mode de transport utilisé. De plus, même si différentes usines étaient alimentées avec le même bois, un panier de produits différents sera produit en raison des configurations internes de chaque usine. Ceci complexifie la planification globale du réseau, car chaque changement aura une répercussion sur l’ensemble du réseau et sur la qualité de la solution.

Ce problème est un bon cas d’utilisation pour notre système, puisque le décideur peut ajuster beaucoup de variables de décision. Par exemple, pour se conformer aux récents évènements et aux contraintes informelles, le décideur pourrait décider d’ajuster les choix de coupes et ainsi les ajustements à effectuer sur l’ensemble du réseau seraient calculés automatiquement. Pour visualiser son réseau, l’entreprise utilise LogiLab, un logiciel spécialisé dans l’optimisa- tion des réseaux d’approvisionnement forestier. La figure 3.11 montre un exemple de réseau présenté par LogiLab. Pour permettre une analyse plus approfondie, un tableau de bord Excel (figure3.12) est généré à l’aide des résultats de l’optimisation. L’entreprise nous a donné accès à son classeur Excel actuellement utilisé pour que nous puissions y ajouter l’interactivité.

Figure 3.11 – Exemple d’un réseau représenté par LogiLab.

C’est avec ce point de départ que nous avons transformé le tableau de bord « statique » en un tableau de bord « dynamique ». La première étape a été d’identifier les variables d’intérêt dans le modèle. Cette étape a mis l’emphase sur l’importance d’ajouter des variables d’agrégation pour représenter certains concepts. Par exemple, la sortie d’une usine correspond à l’ensemble

Figure 3.12 – Exemple d’une page d’un tableau de bord contenant différents graphiques. de la sortie de ses différents processus. Pour pouvoir modifier la sortie totale d’une usine, une variable représentant la somme de tous les processus est alors introduite dans le modèle. Une deuxième considération est l’identification des variables à même le classeur. Comme envi- ron 2000 variables peuvent être modifiées, il est impératif de fournir un système de recherche convivial à l’utilisateur. Ainsi, pour retrouver efficacement les variables, un système de filtre a été mis en place. La figure 3.13 montre un exemple de feuille permettant la modification des variables de transport. Chaque ligne représente une variable et chaque colonne une information relative à cette variable. Pour facilement identifier les variables pertinentes, des filtres (à droite du tableau) permettent de montrer uniquement les variables respectant certains critères. Par exemple, il est possible de montrer uniquement les variables représentant le transport d’un bloc de coupe particulier.

En ce qui a trait aux performances, l’étape de prétraitement des données est la plus exigeante. En effet, pour effectuer les différentes optimisations, environ 52 heures sont nécessaires lors- qu’effectuées sur un ordinateur personnel à l’aide du solveur CPLEX. En utilisant un super ordinateur, il est possible d’exécuter la même tâche en moins de 10 heures. Cependant, une fois ces optimisations effectuées, l’interaction avec l’utilisateur s’effectue en temps réel et sans aucun délai de latence.

Figure 3.13 – Feuille montrant les variables de transport présentes dans le modèle.

Lors de l’utilisation de notre classeur, la situation où la valeur d’une variable se fait continuel- lement effacer (voir section 2.3.2) se présente quelquefois. Ainsi, la possibilité de contraindre une variable à une valeur s’avère nécessaire pour obtenir une expérience utilisateur conviviale. Pour ce faire, nous avons développé un algorithme permettant de « verrouiller » la valeur d’une variable et il fera l’objet du chapitre4. Lors de l’utilisation de cet algorithme sur ce pro- blème, les performances se sont révélées intéressantes. Bien qu’il demande environ 10 minutes pour s’exécuter, notre algorithme est nettement plus rapide que les 52 heures nécessaires pour obtenir le même résultat en utilisant notre engin de prétraitement des données.

Chapitre 4

Ajout de contraintes pour converger

vers la solution désirée

Lors de l’explication de la méthode de Hamel au chapitre 2, nous avons soulevé un pro- blème d’instabilité pouvant survenir lors de l’ajout de préférences. Certaines préférences sont constamment « effacées » par les modifications subséquentes, empêchant ainsi l’utilisateur de tendre vers la solution réellement désirée. Pour contrer ce problème, nous proposons un algo- rithme qui obligera une variable choisie à conserver sa valeur malgré toutes les modifications suivantes.

L’algorithme que nous proposons à cette fin est différent de l’approche qui consisterait à faire une réoptimisation totale à chaque fois. Cependant, l’espace de solutions accessible par l’algorithme est un sous-ensemble de l’espace de toutes les solutions réalisables. Malgré cet effet, nous pensons que la dégradation est suffisamment petite pour que notre algorithme soit utilisable.

Dans le reste de ce chapitre, nous allons dans un premier temps décrire cet algorithme. Par la suite, nous allons mesurer expérimentalement la performance de l’algorithme.

4.1

Description de l’algorithme

L’algorithme est utilisé dans le contexte suivant. Si l’utilisateur est satisfait de la valeur d’une variable, il peut alors demander qu’elle soit « verrouillée » de manière à ce qu’elle ne puisse plus changer même s’il modifie ensuite d’autres variables. L’algorithme prend en entrée une variable (x) et sa valeur (v) et produit un espace de solutions tel que cette variable conserve cette valeur pour toute solution.

Sans l’utilisation de cet algorithme, il faudrait réoptimiser le modèle original en y ajoutant la contrainte supplémentaire x = v. Par la suite, le coûteux processus trouvant les minimums

et les maximums devrait être exécuté à nouveau. Rappelons que pour des modèles industriels étudiés au chapitre 3, plus de 48 heures peuvent être nécessaires pour cette étape.

L’algorithme proposé permet donc de réaliser cette tâche sans délai (mais au prix d’une ré- duction artificielle de l’espace des solutions accessibles). Le texte suivant décrit l’approche proposée.

Géométriquement, un problème contenant n variables représente un espace linéaire à n di- mensions. Chaque point représente une solution et chaque composante d’un point correspond à la valeur d’une variable. Une contrainte d’égalité supplémentaire correspond à un hyperplan traversant cet espace. Lors d’un verrouillage, nous devons donc déterminer l’intersection entre le polytope et l’hyperplan ajouté. Cette opération peut aussi être perçue comme la réduction d’une dimension de notre espace, c’est-à-dire de passer de n dimensions à n− 1 dimensions.

X

Y

𝑠

𝑣

Figure 4.1 – Représentation d’un ajout de contrainte. Sur cette figure, la variable X est contrainte à une valeur v.

Nous déterminons cette intersection en identifiant les points de croisement entre notre polytope et l’hyperplan en utilisant les solutions min et max qui définissaient déjà les sommets de notre polytope. Ainsi, pour chaque paire de sommets, nous devons déterminer si une droite reliant ces deux points croise l’hyperplan.

Y

X

𝑠 𝑣 𝑠𝑘 𝑠𝑙 𝑠′

(a) Exemple d’intersection trouvée grâce à l’utilisation des min et max du polytope.

Y

X

𝑠 𝑠𝑘 𝑠𝑙 𝑣

(b) Exemple de recherche d’intersection ne menant à aucun résultat, puisqu’elle n’existe pas.

Supposons que le décideur analyse un espace solution E contenant n variables et qu’il désire « verrouiller » la jème variable avec la valeur v. Ainsi, pour chaque paire de solutions (sk et sl) provenant de l’espace de solutionsE, nous cherchons à déterminer une valeur α telle que le points0est une nouvelle solution pour laquelle lajème composante a pour valeur v (s0[j] = v). En résolvant l’équation 4.1pour toutes les paires de solutions de l’espace de solutionsE, nous sommes en mesure de trouver ce points0qui se situe quelque part sur la droite reliant les points sk etsl. L’ensemble de cess0 trouvés pour toutes les pairessk etsl détermine les limites d’un nouveau polytope.

αsk+ (1− α)sl= s0

α∈ [0, 1] (4.1)

Pour accomplir cette tâche, notre algorithme fonctionne en deux étapes. Premièrement, un ensemble de solutions (sinter) est trouvé grâce à la combinaison linéaire. Par la suite, un filtrage est effectué pour conserver uniquement la meilleure solution minimum et maximum pour chaque dimension. Pour chaque dimension, nous cherchons donc la solution contenant la plus petite valeur et la solution contenant la plus grande valeur parmi les solutions présentes dans l’ensemble sinter. Ce filtrage permet d’obtenir la solution minimisant chaque variable et la solution maximisant chaque variable tout comme le font les optimisations successives. Ces étapes sont décrites par le pseudo-code de l’algorithme1 et de l’algorithme2.

Algorithme 1 : « Verrouillage » d’une variable Input : solutions, j, v, solutionCourante begin

/* Première étape, recherche de toutes les solutions valides. */ sinter ← solutionCourante; foreachsk∈ solutions do foreachsl∈ solutions \ {sk} do if v ≥ sk[j]∧ v ≤ sl[j] then s0 ← transform(v, j, sk, sl) sinter ← inter ∪ {s0}

/* Deuxième étape, filtrage pour conserver les meilleures solutions. */ minimum← [[0, .., 0], .., [0, .., 0]] maximum← [[0, .., 0], .., [0, .., 0]] foreachd∈ {0..n − 1} do minimum[d]← min p∈interp[d] maximum[d]← max p∈interp[d] return minimum, maximum

Cet algorithme peut facilement être adapté lorsque plusieurs seuils de tolérance sont gérés. Il suffit de l’appliquer pour chaque seuil de tolérance et ainsi obtenir un polytope par seuil de tolérance. Pour un modèle industriel contenant environ 2000 variables d’intérêts et 3 seuils de

Algorithme 2 : transform Input : v, j, sk,sl

/* v doit être entre sk[j] et sl[j]. Ceci est toujours le cas dans notre

algorithme. */ begin smin ← sk smax ← sl if sk[j] > sl[j] then smin ← sl smax ← sk

α ← (v − smax[j])/(smin[j]− smax[j]) s0 = s

minα + smax(1− α) return s0

tolérance, une dizaine de minutes est requise pour effectuer l’opération. Bien que le résultat ne soit pas instantané, il est tout de même beaucoup plus rapide que les 52 heures nécessaires pour sa complète réoptimisation.

Pour diminuer le temps de calcul de notre algorithme, certaines considérations sont nécessaires. Lors de la recherche des points d’intersection, si tous les points sont conservés en mémoire pour uniquement être filtrés à la fin, l’algorithme utilisera trop de mémoire pour être utilisé avec un ordinateur personnel. En effet, chaque solution correspond à un vecteur de « double » d’une dimension égale au nombre de variables (n). Comme un maximum de n2 solutions peut être trouvé, la demande en mémoire grandit rapidement. Par exemple, lors de l’utilisation de notre algorithme pour un problème industriel (environ 2000 variables), plus de 6 Go de mémoire était requis.

Il est donc impératif de fournir une implémentation efficace pour permettre l’utilisation de cet algorithme pour des problèmes industriels. Des tests ont conclu que simplement sérialiser des solutions sur le disque est trop coûteux, même si l’enregistrement est effectué de manière asynchrone. Pour améliorer les performances, une solution mettant à profit l’indépendance des deux étapes a été produite. En effet, le filtrage des meilleures solutions peut s’effectuer en parallèle de la recherche des intersections entre le polytope et l’hyperplan. Pour que le résultat de l’algorithme demeure valide, il suffit que toutes les paires de points soient traitées.

Pour ce faire, deux « threads » fonctionnent en parallèle. Le premier est responsable de trouver les intersections entre les paires de points. Lorsqu’un certain nombre de ces points sont trouvés, ils sont insérés dans un tampon commun aux deux « threads ». La tâche du deuxième « thread » est de trouver les meilleurs points pour chaque dimension. Cette implémentation possède l’avantage de libérer les points à mesure qu’ils sont trouvés et la dimension de la file peut être paramétrée, limitant par le fait même la mémoire nécessaire.

4.1.1 Inconvénient de notre algorithme

Bien que plus rapide que l’utilisation d’un solveur mathématique, notre algorithme présente un inconvénient. Lors de son utilisation, il réduit davantage le nombre de solutions atteignables par le décideur que l’utilisation d’un solveur. Géométriquement, cette diminution est comparable à la diminution du volume du polytope.

Cet effet est présent, parce que notre polytope original est en réalité un sous-espace de toutes les solutions optimales disponibles. Refaire une optimisation complète permettrait d’étendre le polytope trouvé aux limites de l’espace des solutions réalisables. Ainsi, notre algorithme retourne un sous-ensemble d’un sous-ensemble qui n’était pas lui-même complet. Cet effet est représenté à la figure 4.3. Sur cette figure, les points rouges représentent les solutions qui seraient retournées par un solveur suite à une réoptimisation complète lors de l’ajout d’une contrainte. En contrepartie, les points noirs (intersection de l’hyperplan avec les droites reliant entre eux les points orange et les points verts) représentent les points retournés par notre algorithme. Ainsi, il est possible d’observer que les points rouges sont plus distants les uns des autres que les points noirs. Cette plus grande distance procure une plus grande plage de valeurs possibles pour cette variable. Pour caractériser cette réduction, nous avons conduit des expérimentations qui feront l’objet de la section suivante.

Y

𝑠′𝑦 𝑠′𝑦

X

𝑠

Documents relatifs