Optimisation linéaire 2016 - 2017 Optimisation Linéaire - TP Le but de ce projet, se déroulant sur plusieurs séances, est de programmer l’algorithme du simplexe. L’algorithme devra lire le problème linéaire dans un fichier, le résoudre puis afficher la solution optimale trouvée (si elle existe). Remarque : Le fichier Simplexe.java peut être téléchargé sur la page : https://lipn.univ-paris13.fr/~lacroix/Documents/RO/Simplexe.java. Ce fichier contient le code permettant de lire des nombres dans un fichier. Il peut servir de base pour ce projet. Il est possible de choisir un autre langage de programmation. Structure de données utilisée Le problème à résoudre sera sous forme canonique, c’est-à-dire sous la forme : max cT x Ax ≤ b x≥0 On supposera que les variables du problème sont les variables x1 , . . . , xn . Pour poser le problème sous forme standard, il faut alors ajouter une variable d’écart par contrainte. La variable xn+i , i = 1, . . . , m, correspondra à la variable d’écart ajoutée dans la contrainte numéro i. Pour stocker et résoudre le problème, on utilisera une matrice de taille (m + 1) × (m + n + 2). La première ligne correspondra aux coefficients des variables dans la fonction objectif. Les m lignes suivantes correspondront aux coefficients des variables dans les contraintes. Les colonnes d’indice 1, . . . , n + m seront associées aux variables x1 , . . . , xn+m , la dernière colonne correspondra à la valeur du membre de droite de la contrainte. Remarque : La colonne d’indice 0 ne sera pas utilisée. Elle servira au besoin pour la variable supplémentaire introduite dans le PL lors de la recherche d’une solution initiale (variable x0 dans le cours). On n’en tient pas compte pour l’instant. À titre d’exemple, le PL initial : max 40x1 + 50x2 2x1 + x2 ≤ 800 x1 + 2x2 ≤ 700 x2 ≤ 300 x1 , x2 ≥ 0 Mathieu LACROIX 1 IUT Villetaneuse Optimisation linéaire 2016 - 2017 dont la modification en PL stantard est : max 40x1 + 50x2 2x1 + x2 + x3 = 800 x1 + 2x2 + x4 = 700 x2 + x5 = 300 x1 , x2 , x3 , x4 , x5 ≥ 0 sera stocké sous la forme : 0 0 0 0 40 2 1 0 50 1 2 1 0 1 0 0 0 0 1 0 0 0 0 1 0 800 700 300 Fichiers d’instances Les données du problème linéaire sous forme canonique à résoudre seront lues dans un fichier respectant la syntaxe suivante : n m c1 a11 ... cn ... a1n ... amn b1 ... am1 bm où — — — — : n représente le nombre de variables (sans les variables d’écart), m correspond au nombre d’inégalités (de type ≤), cj , j = 1, . . . , n, correspond au coefficient de la variable xj dans la fonction objectif, aij , j = 1, . . . , n, i = 1, . . . , m, correspond au coefficient de la variable xj dans la contrainte numéro i, — bi , i = 1, . . . , m, correspond à la valeur du membre de droite de la contrainte numéro i. Question 1 : Définir la structure de données permettant de stocker le problème linéaire. Question 2 : Définir la fonction/méthode/constructeur prenant en paramètre un nom de fichier et initialisant la structure avec les valeurs correctes. Question 3 : Définir la fonction (ou méthode) affichant la structure de données. Implémentation de l’algorithme du simplexe (une phase) On supposera dans cette partie que la solution x1 = · · · = xn = 0 est une solution admissible. Autrement dit, les membres de droite des contraintes sont tous positifs ou nuls. L’algorithme est le même que celui vu en cours. Cependant, afin de programmer l’algorithme facilement, on n’utilisera plus les dictionnaires. On continuera à travailler sur la Mathieu LACROIX 2 IUT Villetaneuse Optimisation linéaire 2016 - 2017 structure de données, c’est-à-dire la matrice de taille (m + 1) × (m + n + 2). Cela ne modifie en rien l’algorithme mais simplifie sa programmation. Pour donner un exemple, si l’on résout le problème linéaire correspondant à l’exemple de la fabrication de yaourts donné en cours (en notant les variables xA et xN par x1 et x2 , et les variables e1 , e2 et e3 par x3 , x4 et x5 ), la forme standard de ce problème est le deuxième exemple donné dans ce sujet. Première itération La variable entrante est x1 (première variable dont le coefficient dans la fonction objectif est strictement positif). La variable sortante est x3 . Le changement de variable (appelé pivot) modifie la structure de données pour donner : 0 0 0 0 0 1 0 0 30 -20 1 2 3 2 1 2 - 12 1 0 0 0 1 0 0 0 0 1 -16000 400 300 300 La dernière valeur de la première ligne de la matrice correspond à l’opposé de la valeur de la fonction objectif pour la solution (400, 0, 0, 300, 300). Deuxième itération La variable entrante est x2 , et la variable sortante est x4 . Le pivot donne la matrice suivante : 0 0 0 0 0 1 0 0 0 0 1 0 -10 2 3 - 13 1 3 -20 - 31 2 3 - 32 0 0 0 1 -22000 300 200 100 Troisième itération Aucune variable n’a de coefficient strictement positif dans la fonction objectif, la solution courante est optimale. Remarque : Il n’est pas nécessaire de connaître quelles sont les variables en base pour faire tourner l’algorithme. Cela sert uniquement pour l’affichage de la solution optimale à la fin. (On peut cependant les déterminer puisque les variables de base forment la matrice identité (à permutation près)). Question 4 : Déterminer l’algorithme permettant de trouver l’indice de la variable entrante. Implémenter la fonction (ou méthode) varEntrante retournant l’indice de la variable entrante (-1 s’il n’y a pas de variable entrante). Question 5 : Déterminer l’algorithme permettant de trouver, à partir de l’indice de la variable entrante, l’indice de la contrainte limitant la valeur maximum que peut prendre la variable entrante. Implémenter la fonction (ou méthode) varSortante retournant l’indice de la ligne correspondant à la contrainte limitante (-1 s’il n’y a pas de variable sortante). Question 6 : Déterminer l’algorithme correspondant au pivot (mise-à-jour de la matrice) en fonction des indices des variables entrante et sortante. Implémenter la fonction (ou méthode) pivot associée. Question 7 : Définir la fonction (ou méthode) solve permettant de résoudre le problème linéaire. Elle renverra true si le problème est optimal, et false s’il est non borné. Mathieu LACROIX 3 IUT Villetaneuse Optimisation linéaire 2016 - 2017 Question 8 : Pour afficher la solution optimale, il faut connaître les variable en base. La méthode la plus simple pour les connaître consiste à stocker les indices des variables en base à chaque itération. Pour cela, on utilise un tableau de taille m dont chaque case contient l’indice de la variable de base associée à l’inégalité. Ajouter ce tableau et le mettre à jour durant l’algorithme de résolution du simplexe. Ajouter une fonction (ou méthode) afficheSolution affichant la solution optimale, ainsi que le coût de cette solution. Implémentation de l’algorithme du simplexe en deux phases Si les membres de droite ne sont pas tous positifs ou nuls, il convient de faire une première phase (résolution d’un simplexe sur un problème auxiliaire) afin de trouver une solution réalisable. Implémenter l’algorithme du simplexe à deux phases. Mathieu LACROIX 4 IUT Villetaneuse