Vous êtes sur la page 1sur 19

Mardi, le avril 2019

TP 02 : Résoudre des Programmes Linéaires à l’aide de


GLPK (GNU linear programming kit)
GNU Linear Programming Kit (GLPK) est un logiciel dédié à la résolution des programmes
linéaires (PLs), et des programmes linéaires à variables mixtes. GLPK a été conçu (en ANSI C)
par Andrew Makhorin du département d’informatique appliquée, institut de l’aviation de Moscou
en Russie. GLPK fait partie du projet GNU et est publié sous licence GNU General Public License
(GPL). Le package GLPK comprend principalement les composants suivants :

— Méthode simplex révisée (pour les PLs).


— Méthode du point intérieur Primal-Dual (pour les PLs).
— Méthode par séparation et évaluation (pour les PLNEs).
— Traducteur pour le langage de modélisation GNU MathProg.
— Application Program Interface (API).
— glpsol, solveur autonome des PLs.

Données :
(GMPL .dat)

Modèle sous format :


Solution :
- MathProg/GMPL .mod Solveur :
fichier séquentielle
- CPLEX LP glpsol
(.txt,.out,.sol, . . . )
- MPS . . . etc.

Figure 1 – Schéma d’utilisation du GLPK

GLPK peut traiter des programmes linéaire fournis sous différents formats : CPLEX LP, MPS,
ou décrits à partir d’un langage spécialisé, appelé modeleur GNU MathProg, en séparant les données
(fichiers .dat) du modèle (fichier .mod).

1 Installation et documentation officielle : liens utiles


Installez GLPK et GUSEK. Lisez le guide de l’utilisateur Modeling Language GNU MathProg
fourni avec GLPK. Les instructions d’installation et la documentation détaillée sont également dispo-
nibles sur :
— GLPK sous Linux : www.gnu.org/software/glpk/,
— Si vous utilisez Ubuntu, lancez simplement la commande :

>> sudo apt - get install glpk

— GLPK sous Windows (WinGLPK) : winglpk.sourceforge.net/,


— Guide d’installation sous Windows 10 : http://www.osemosys.org/uploads/1/8/5/0/18504136/
glpk_installation_guide_for_windows10_-_201702.pdf

1
— GLPK code source : ftp://ftp.funet.fi/pub/gnu/prep/glpk/,
— GUSEK (GLPK Under SciTE Extended Kit), une GUI pour GLPK : gusek.sourceforge.
net/.
— Manuel du langage MathProg/GMPL (GNU Mathematical Programming Language) : en an-
glais, gusek.sourceforge.net/gmpl.pdf. En français, http://lim.univ-reunion.fr/staff/
fred/Enseignement/Optim/doc/GLPK/CoursGLPK.pdf.

2 Langage de Modélisation basique : CPLEX LP Format (".lp")


GLPK peut donc lire différents formats d’entrée. Le plus simple a été créé pour le solveur CPLEX.
Il revient à écrire un PL ou un PLNE sous le format habituel.

<Max,Min>imize
<étiquette> : <fonction objectif>, format : s r x s r x ... s r x
<Subject To, such that, s.t., st., st>
<étiquette> : <Contrainte> format : s c x s c x ... s c x (<=, >=, >, <, =) b
...
Bounds
<Borne> format : x >(=) l, l <(=) x <(=) u, x = t, x free.
...
<Integer, general, binary>
<variable>
...

Où <fonction objectif> est remplacé par un nom symbolique de la fonction objectif, <étiquette
contr.> est remplacé par un nom symbolique d’une contrainte (par exemple : disponibilité), s est un
signe + ou -, c est une constante numérique qui désigne un coefficient objectif, x est un symbole nom
d’une variable. Voici un petit exemple de programme linéaire sous le format CPLEX LP :

 max Z(x) = C T x,

 Maximize
(P L) s.c. Ax ≤ B, obj: x1 + 2 x2 + 3 x3 + x4


 xi ∈ Di , ∀i ∈ {1, . . . , n}. Subject To
 c1: - x1 + x2 + x3 + 10 x4 <= 20
 max Z(x) = x1 + 2 x2 + 3 x3 + x4 ,



 c2: x1 - 3 x2 + x3 <= 30


 s.c.

 c3: x2 - 3.5 x4 = 0
−x1 + x2 + x3 + 10 x4 ≤ 20




 Bounds
− 3 x2 + x3 ≤ 30


 x1

 0 <= x1 <= 41.5
(P) x2 − 3.5 x4 = 0
 x3 <= 4
0 ≤ x ≤ 40,

1




 2 <= x4 <= 3
x3 ≤ 4,


Integer



≤ ≤


 2 x 4 3,


 x3
x2 ∈ R+ , x3 , x4 ∈ N.


x4
End

2
Remarques :
— Un point-virgule doit mettre fin à chaque ligne de code ("instruction"),
— les noms des variables, objectifs et contraintes sont obligatoires, ne peut contenir d’espaces, et
ne peut être répétés.

1) Créer le fichier Premier.lp contenant le modèle ci-dessus.

2.1 Compilation/résolution

Afin de résoudre le LP (lancer le solveur glpsol) défini dans le fichier premier.lp sous format
CPLEX LP, utilisez la ligne de commande ci-dessous. Le résultat est écrit dans le fichier premier.sol.

>> glpsol -- cpxlp premier . lp -- output premier . sol

Ou, suivre les étapes suivantes pour résoudre le PL sous GUSEK :


— Cliquer sur menu Tools → Go pour résoudre votre modèle (ou même, tapper F5).
— Afin d’afficher la solution, sélectionner l’option Tools → Generate Output on the Fly.

2) Résoudre le PL défini dans le fichier premier.lp. Commenter sur la qualité de solution fournie.
Justifier votre réponse.

2.2 Fichier de sortie

glpsol peut fournir en sortie un fichier séquentielle donnant la solution du PL ou du PLNE. Le


tableau suivant est le fichier correspondant au programme précédent. Il indique le statut de la solution
(optimale ou irréalisable) et la valeur de la fonction objective optimale. Dans le cas d’un PLNE,
une valeur supplémentaire finissant par (LP) est en fait la valeur du PLNE relaxée des contraintes
d’intégrité.

Problem:
Rows: 3
Columns: 4 (2 integer, 0 binary)
Non-zeros: 9
Status: INTEGER OPTIMAL
Objective: obj = 77.5 (MAXimum)

No. Row name Activity Lower bound Upper bound


------ ------------ ------------- ------------- -------------
1 c1 3 20
2 c2 14 30
3 c3 0 0 =

No. Column name Activity Lower bound Upper bound


------ ------------ ------------- ------------- -------------
1 x1 41.5 0 41.5
2 x2 10.5 0
3 x3 * 4 0 4
4 x4 * 3 2 3

3
Integer feasibility conditions:

KKT.PE: max.abs.err = 0.00e+00 on row 0


max.rel.err = 0.00e+00 on row 0
High quality

KKT.PB: max.abs.err = 0.00e+00 on row 0


max.rel.err = 0.00e+00 on row 0
High quality

End of output

2.2.1 Interprétation des résultats

Le fichier Premier.sol généré par le solveur, contenant la solution du modèle, est divisé en quatre
parties. Noter que les détails décrits dans ce fichier peuvent différer selon le langage de modélisation
utilisé.
1. Informations sur le problème et la valeur de la fonction objectif obtenu.

Problem:
Rows: 3
Columns: 4 (2 integer, 0 binary)
Non-zeros: 9
Status: INTEGER OPTIMAL
Objective: obj = 77.5 (MAXimum)

2. Quelques détails sur la fonction objectif et/ou contraintes (la fonction objectif figure dans le
cas l’un modèle GMPL).

No. Row name Activity Lower bound Upper bound


------ ------------ ------------- ------------- -------------
1 c1 3 20
2 c2 14 30
3 c3 0 0 =

3. Préciser les détails des variables de décision et leur valeurs obtenu (le symbole ’*’ signifie que
la variable correspondante est entière).

No. Column name Activity Lower bound Upper bound


------ ------------ ------------- ------------- -------------
1 x1 41.5 0 41.5
2 x2 10.5 0
3 x3 * 4 0 4
4 x4 * 3 2 3

4. Informations sur les conditions d’optimalité (conditions de Karush-Kuhn-Tucker).

Integer feasibility conditions:

4
KKT.PE: max.abs.err = 0.00e+00 on row 0
max.rel.err = 0.00e+00 on row 0
High quality

KKT.PB: max.abs.err = 0.00e+00 on row 0


max.rel.err = 0.00e+00 on row 0
High quality

3 Langage GMPL/AMPL (GNU MathProg Language)


GMPL est un langage de modélisation qui permet de simplifier la modélisation d’un problème
d’optimisation à l’aide d’ensembles, de sommes, etc. Voici une description courte et simplifiée du
langage.
Remarques :
— Chaque variable a un nom (x1, x2, etc.), la fonction objectif a un nom (z, objectif, etc.)
et chaque contrainte a un nom (con1, c1, contrainte, etc.).
— Vous êtes libre de choisir des noms, mais ils doivent être différents.
— Pour écrire des commentaires sur le modèle, utilisez d’abord le signe #.
— Chaque ligne doit se terminer par un point-virgule (;).
— Pour résoudre le même modèle avec plusieurs données différentes, il est préférable de séparer
le modèle et les données.
Considérons la formulation générale d’un PL :


 Xn
ci xj ,

max Z(x) =





 j=1
 n
(P L)
X
 s.t. aij xj ≤ bi , i ∈ {1, . . . , m}

j=1





xj ≥ 0, ∀j ∈ {1, . . . , n},


Ensuite, le fichier modèle (.mod) pour GMPL est créé comme suit. Nous utilisons les paramètres
introduits, bien qu’ils n’ont pas encore de valeurs numériques.

param n; # nombre de variables


param m; # nombre of constraints
param c{1..n}; # coefficients de la fonction objectif
param a{1..m,1..n}; # Matrice de contraintes
param b{1..m}; # Bornes des contraintes
var x{1..n} >= 0; # Variables de décision
maximize objectif: sum{j in 1..n} c[j]*x[j];
subject to contrainte{i in 1..m}: sum{j in 1..n} a[i,j]*x[j] <= b[i];
end;

3) Créer le fichier Premier.mod contenant le modèle défini ci-dessus.

5
Ici n, m, c, a et b sont des paramètres (param) et x sont des variables (var). n est le nombre
de variables et m est le nombre de contraintes. {1. . . n} est l’ensemble des indices de tous variables
et {1. . . m} est l’ensemble des indices de toutes les contraintes. sum{j in 1...n} est une somme sur
l’ensemble des indices de toutes les variables ( nj=1 ).
P

Le fichier contenant les données numériques sera défini comme suit. Voici les valeurs pour tous les
paramètres qui ont été déclarés dans le fichier de modèle doivent être affectés.

param n := 4; #nombre de variables


param m := 3; #nombre contraintes
param : c :=
1 5
2 6
3 2
4 4;
param a : 1 2 3 4 :=
1 3 2 1 5
2 2 1 2 4
3 3 -3 4 5;
param : b :=
1 80
2 45
3 80;
end;

Ceci revient à résoudre le programme linéaire suivant :






 max Z(x) = 5 x1 + 6 x2 + 2 x3 + 4 x4 ,
 s.c.




+ 5 x4 ≤ 80,

 3 x1 + 2 x2 + x3
(P)


 2 x1 − x2 + 2 x3 + 4 x4 ≤ 45,

3 x1 − 3 x2 + 4 x3 + 5 x4 ≤ 80,






xi ≥ 0, ∀i ∈ {1, . . . , n}.

On peut remarquer qu’il est nécessaire de fournir les indices pour les vecteurs (c) et (b), et les indices
de lignes et de colonnes pour les matrices (a).
4) Créer le fichier Premier.dat contenant les données défini ci-dessus.

3.1 Compilation/résolution

Afin de résoudre le LP (lancer le solveur glpsol) défini dans le fichier Premier.mod sous format
GMPL, utilisez la ligne de commande ci-dessous. Le résultat est écrit dans le fichier premier.sol.

>> glpsol -m Premier . mod -d Premier . dat -- output Premier . sol

Afin de résoudre le PL sous GUSEK cliquer sur menu Tools → Go pour résoudre votre modèle
(ou même, tapper F5).

6
3.2 Fichier en sortie
Problem: Premier
Rows: 4
Columns: 4
Non-zeros: 16
Status: OPTIMAL
Objective: objectif = 901.1 (MAXimum)

No. Row name St Activity Lower bound Upper bound Marginal


------ ------------ -- ------------- ------------- ------------- -------------
1 objectif B 901.1
2 contrainte[1]
B 58.9 120
3 contrainte[2]
NU 80 80 10.9
4 contrainte[3]
NU 97 97 0.3

No. Column name St Activity Lower bound Upper bound Marginal


------ ------------ -- ------------- ------------- ------------- -------------
1 x[1] NL 0 0 -7.7
2 x[2] B 12.6 0
3 x[3] B 33.7 0
4 x[4] NL 0 0 -31.1

Karush-Kuhn-Tucker optimality conditions:

KKT.PE: max.abs.err = 0.00e+00 on row 0


max.rel.err = 0.00e+00 on row 0
High quality

KKT.PB: max.abs.err = 0.00e+00 on row 0


max.rel.err = 0.00e+00 on row 0
High quality

KKT.DE: max.abs.err = 1.78e-15 on column 2


max.rel.err = 7.79e-17 on column 2
High quality

KKT.DB: max.abs.err = 0.00e+00 on row 0


max.rel.err = 0.00e+00 on row 0
High quality

End of output

3.3 Syntaxe (GMPL)

Nous décrivons ci-dessous les commandes les plus récurrentes dans GMPL. Notez que GMPL fait
la distinction entre les lettres majuscules et minuscules, et que chaque commande ou déclaration doit
se terminer par " ;" (point-virgule).

7
3.3.1 param

param est réservé à la déclaration des constantes, l’affectation des valeur est faite comme suit :

param <nom> := <valeur>; # déclaration d’une constante


param : <nom> := 1 <val1> <val2> ... <valn>; # déclaration d’un vecteur ligne
param : <nom> := 1 <val1> # déclaration d’un vecteur colonne
2 <val2>
.
n <valn>;
param <nom> : <indices colonnes> : =
<indice ligne> <val11> <val12> ...
<indice ligne> ... <val22> ... ;

Exemple :

param n := 7;
param : vec := 1 50 2 75 3 100; # vec = [50 2 75 3 100]
param : vec2 := 1 34 2 105 3 65 4 120; # vec2 = [34 2 105 3 65 4 12]
param matr : 1 2 3 : = \* matr = [ 80 9 77 ; 11 120 13 ]
1 80 9 77
2 11 120 13;

3.3.2 set

set réservé à la déclaration des ensembles. Notez qu’un ensemble peut contenir des valeur numé-
rique ou symbolique (chaîne de caractère).

set <nom> := <elt1> <elt2> ... <eltn>;

Exemple :

set voitures := SAAB VOLVO BMW;


set impair := 1 3 5 7 9;
set semaines := 1..N; # précédé par : param N := valeur;

3.3.3 var

var réservé à la déclaration des variables de décision.

var <nom>{<ensemble>} <borne1>, <borne2>, ... ;

Exemple :

var x{1..n} >=0; # vecteur de variables positives non-nulles


var x{1..8,1..20}; # matrice de variable 8x20

8
var y{voiture} binary; \* vecteur de variables binaire y[i] pour tout élément
dans l’ensemble voiture *\
var y{1..n} >=0,<=4; # vecteur de variables y[i] bornée, où 0<=y[i]<=4, i=1..n
var w{1..m} >=0, integer; # vecteur de variables entière positives non-nulles

3.3.4 sum

sum réservé à la déclaration des sommes sur les variables, et les constantes (dans la fonction objectif
ou contraintes).

sum{<variable inter> in <ens 1>, <variable inter> in <ens 2>, ... } <expression>;

Exemple :

sum{i in voiture} poids[i];


sum{i in 1..20} (x[i] - y[i]);
sum{i in A, j in B} z[i,j];

3.3.5 maximize/minimize

Spécifie le type de la fonction objectif. Le nom est suivit par ":" et par la fonction objectif.

<max, min>imize <nom>: <expression de la fonction objectif>;

Exemple :

maximize profit: sum{i in voiture} g[i] * x[i];


minimize cout: sum{i in ville, j in depot} d[i, j] * x[i, j];

3.3.6 subject to

Déclare une ou un ensemble de contraintes. Les contraintes doivent avoir des noms différents. Le
nom est suivi du symbole ":" (deux points), et son expression.

subject to
<étiquette> : <expression>;
subject to <étiquette>{<ensemble>} : <expression>;

Exemple :

subject to constraint1: x + y = 7;
subject to storage{i in Produkter}:
produced[i] + left[i] - sold[i] <= storagecap[i];
subject to con3{i in 1..n}:
sum{j in 1..i} x[j] >= d[i];

9
3.3.7 solve

Instruction/commande pour lancer la résolution (i.e., le solveur glpsol).

3.3.8 display

Afficher des information, e.g. une solution.

display x; # affiche le vecteur x


display x > fichier.res; # écrire le vecteur x dans un fichier ’fichier.res’
display cont1.dual; # Affiche la variable dual qui correspond à une contrainte "cont1"
display x.rc; # Affiche le coût réduit par une variables x

3.3.9 printf

De même que la commande display.

printf{i in 1..8, j in 1..8: x[i,j]>0}: "Pos (%d,%d)\n",i, j;


printf{j in ensemble : x[j]>0} " x(%d)=%.2f\n",j,x[j];
printf "Optvariabler:"; printf{j in 1..n: x[j]>0} " %d",j; printf "\n";

3.3.10 end

Tout fichier écrit en langage GMPL (.mod et .dat) doit se terminer par le mot réservé end.

3.4 Conversion GMPL vers CPLEX LP

L’ensemble de fichiers écrit en langage GMPL (.mod et .dat) peuvent être convertis en langage
basique CPLEX LP, cela en utilisant la commande suivante :

>> glpsol -- check -- math Premier . mod -d Premier . dat -- wcpxlp Premier . lp

Cette procédure produit le fichier "Premier.lp" suivant :

\* Problem: Premier *\

Maximize
objectif: + 15 x(1) + 10 x(2) + 23 x(3) + 14 x(4)

Subject To
contrainte(1): + 3 x(1) + 2 x(2) + x(3) + 5 x(4) <= 120
contrainte(2): + 2 x(1) + x(2) + 2 x(3) + 4 x(4) <= 80
contrainte(3): + 3 x(1) - 3 x(2) + 4 x(3) + 5 x(4) <= 97

End

10
4 Quelques modèles classiques
Dans le reste de ce TP, on va traiter une variété de problèmes d’optimisation combinatoire clas-
siques de la recherche opérationnelle ("problèmes de référence"), suivant le processus naturelle souvent
rencontrée par un ingénieur en recherche opérationnelle :
1. Énoncé du problème d’optimisation,
2. Modélisation par un programme mathématique (ici, linéaire),
3. Structuration des données suivant le modèle défini,
4. Identification de la méthode adéquate pour la résolution ; ici, on utilise le solveur GLPK :
a. Traduire le modèle en langage du modeleur choisi (CPLEX LP, GMPL,. . . etc.),
b. Création de(s) fichier(s) de données dans le cas de GMPL,
c. Résolution (i.e., faire appel au solveur glpsol).
5. Interprétation des résultats (retranscription au langage compréhensible par le décideur, si pos-
sible et/ou nécessaire).

4.1 Problème de sac à dos (Knapsack Problem, KP)

Étant donné plusieurs objets possédant chacun un volume/poids et une valeur/profit et étant
donné un volume/poids maximum pour le sac. On cherche à savoir quels objets faut-il mettre dans le
sac de manière à maximiser la valeur totale sans dépasser le volume/poids maximal autorisé pour le
sac ?
Ne vous laissez pas tromper par la simplicité de l’énoncé, car ce problème est de classe N P-difficile !
Le modèle mathématique correspondant est le suivant :

 Xn




 max Z(x) = cj xj ,

 j=1


 s.c.

(P) Xn



 vj xj ≤ V,
j=1





xj ∈ {0, 1}, ∀j ∈ {1, . . . , n}.


Où, cj représente le profit correspondant au choix du j eme objet, vj est le volume/poids du j eme
objet, W est la capacité maximale du sac, xj représente la variable de décision :
(
1 si l’objet j est choisit,
xj =
0 sinon.

Ainsi, lors de la résolution de ce problème, il faut récolter des données suivant la structure de données
de ce modèle :
— Vecteur de profits : C = (c1 , c2 , . . . , cn ),
— Vecteur ce poids de chaque objet : v = (v1 , v2 , . . . , vn ),
— Valeur de la capacité maximale du sac : V .

11
4.1.1 Exemple illustratif :

Donnons une instance, présenté ci-dessous, à quatre objet de différentes volumes et profits.

Objet i : ci , bi
Volume bi

Objet 1 : 1, 3

Objet 2 : 2, 6

Objet 3 : 8, 5

Objet 4 : 14, 2

Sac de capacité 10
14, 2 2, 6
profit total = 16

4.1.2 Résolution à l’aide de GLPK

CLPEX LP
\* Problem: sac à dos *\

Maximize
f: + 12 x(1) + 15 x(2) + 5 x(3) + 16 x(4) + 17 x(5)

Subject To
cap : + 3 x(1) + 6 x(2) + x(3) + 7 x(4) + 888 x(5) <= 23

Bounds
0 <= x(1) <= 1
0 <= x(2) <= 1
0 <= x(3) <= 1
0 <= x(4) <= 1
0 <= x(5) <= 1

Generals # on peut la remplacer par binary et enlever les bornes


x(1)
x(2)
x(3)
x(4)
x(5)

End

GMPL

- Fichier .mod

12
#Problème du sac a dos
#Paramètres
param n ; # nombre d’objets
param C{i in 1..n}; # utilité/profit de l’objet i
param A{i in 1..n}; # volume de l’objet i
param B; # capacité du sac
# variables de désicion
var x{1..n} binary;
# Fonction objectif
maximize f :sum {i in 1..n} C[i]*x[i] ;
# contraintes
s.t. cap : sum{i in 1..n} A[i,j]*x[i] <= B[j] ;
printf "------Début de la résolution -----\n";
solve;
printf "------Fin de la résolution -----\n";
display x;
end;

- Fichier .dat

data;
param n := 5;
param C := 1 12
2 15
3 5
4 16
5 17;
param A := 1 3
2 16
3 1
4 7
5 18;
param B := 23;
end;

4.1.3 Devoir *

Considérons le modèle mathématique suivant :



 Xn




 max Z(x) = cj xj ,

 j=1


 s.c.

(P) Xn



 vij xj ≤ Vi , ∀i ∈ {1, . . . , m},
j=1





xj ∈ {0, 1}, ∀j ∈ {1, . . . , n}.


Ce modèle est une variante du problème de sac à dos, connu sous le nom de Problème de sac à dos
multidimensionnelle (Multidimensional Knapsack Problem, MKP).

13
5) En se basant sur le fichier .mod du KP, écrire le modèle du MKP en langage GMPL. Générer et
résoudre une instance aléatoire de taille n = 40.

4.2 Problème de transport (Transportation Problem)

Une entreprise produit des biens dans n centres d’approvisionnement. L’offre produite au centre
d’approvisionnement i est ai . La demande pour le bien est répartie sur m différents centres de demande.
La demande du j ème centre de demande est bj . Le problème de l’entreprise est d’acheminer les
marchandises des centres d’approvisionnement aux centres de demande à un coût minimal. Supposons
que le coût d’expédition d’une unité du fournisseur au centre de demande est égal à cij et que le coût
d’expédition est linéaire. La formulation mathématique de ce problème est la suivante :

 Xn X m
min Z(x) =



 cij xij ,

i=1 j=1



s.c.






 Xm
xij ≤ ai , ∀i ∈ {1, . . . , n},

(P)

 j=1


 Xn
xij ≥ bi , ∀i ∈ {1, . . . , m},







 i=1

xij ≥ 0, ∀i ∈ {1, . . . , n}, ∀j ∈ {1, . . . , m}.


Où la variable de décision xij représente la quantité transporté d’un centre d’approvisionnement i


vers un point de demande j.
Ainsi, lors de la résolution de ce problème, il faut récolter des données suivant la structure de
données de ce modèle :
— Matrice de coûts de transport : (cij )1≤i≤n,1≤j≤m ,
— Vecteur d’offres des points d’approvisionnement : a = (a1 , a2 , . . . , an ),
— Vecteur de demandes : b = (b1 , b2 , . . . , bn ),

4.2.1 Exemple illustratif

On se donne une instance, présenté ci-dessous, à deux centres d’approvisionnement et trois points
de demande.

20 15
Offre

5 4 6 5 7 3

Demande
20 15 15

14
Le modèle associé est le suivant :



 max Z(x) = 3 x11 + 4 x12 + 6 x13 + 5 x21 + 7 x22 + 5 x23 ,




 s.c.

x11 + x12 + x13 ≤ 15,





≤ 20,

 + x21 + x22 + x23
(P)


 x11 + x21 ≥ 17,

x12 + x22 ≥ 8,









 + x13 + x23 ≥ 10,

xij ≥ 0, ∀i ∈ {1, 2}, ∀j ∈ {1, 2, 3}.

4.2.2 Résoudre à l’aide de GLPK

GMPL

- Fichier .mod
set O; /* Ensemble de dépôts (points d’offre) */
set D; /* Ensemble de points de demandes */
param a{i in O}; /* capacités des points d’offre */
param b{j in D}; /* Demande */
param d{i in O, j in D}; /* distance entre les points d’offre et de demande */
param f; /* coût de transport par unité */
param c{i in O, j in D} := f * d[i,j] / 1000;
/* coût de transport en milliers d’unité monétaire */
var x{i in O, j in D} >= 0;
/* variable de décision : quantités transporté */
minimize cout: sum{i in O, j in D} c[i,j] * x[i,j];
/* coût total de transport en milliers d’unité monétaire */
s.t. Offre{i in O}: sum{j in D} x[i,j] <= a[i];
/* respecter la limite d’approvisionnement au point d’offre i */
s.t. demande{j in J}: sum{i in I} x[i,j] >= b[j];
/* satisfaire la demande sur le marché j */

- Fichier .dat
set O := Annaba Oran;
set D := Tindouf Ourgla Tizi_ouzou;
param a := Annaba 1050
Oran 1800;
param b := Tindouf 975
Ourgla 900
Tizi_ouzou 825;
param d : Tindouf Ourgla Tizi_ouzou :=
Annaba 2.5 1.7 1.8
Oran 3.5 1.8 1.4 ;
param f := 1000;
end;

6) Reprendre le même modèle avec contraintes d’égalité. Ensuite, générer et résoudre une instance
de taille 10 (en format GMPL, puis en CPLEX LP).

15
4.3 Couplage maximum (Maximum Matching Problem)

Soit G = (V, E) un graphe simple. Rappelons qu’on peut représenter un tel graph par une matrice
A = (aij )1≤i≤n,1≤j≤n carrée, symétrique, avec :
(
1 si {i, j} ∈ E,
aij =
0 sinon.

Cette nouvelle structure représentative est dite matrice d’adjacence associé au graphe G.
Un couplage M dans un graphe est un sous-ensemble d’arêtes deux à deux disjointes (i.e., M ⊆ E
et ∀ e1 = {u1 , u2 }, e2 = {v1 , v2 } ∈ M, e1 6= e2 , e1 ∩ e2 = ∅). On peut associer à cette notion le problème
d’optimisation consistant à trouver un couplage de taille maximale. Les programmes linéaires (P1 ) et
(P2 ) sont deux modèles possibles pour le problème de couplage maximum. Vous pouvez remarquer que
(P1 ) est plus facile à interpréter en langage informatiques ; car, il se base sur des structures prédéfinis
dans les langages de modélisation (ici, on parle de CPLEX LP, GMPL).

Xn X n 
X

max Z(x) = x , max Z(x) = xe ,
 
ij

 


 



 i=1 j=1 

 e∈E
 s.c.
  s.c.

(P1 ) n (P2 ) X
X x{u,v} ≤ 1, ∀ v ∈ V,
aij xij ≤ 1, ∀i ∈ {1, . . . , n},

 

 

 
 u∈N (v)

 j=1 

  xe ∈ {0, 1}, ∀ e ∈ E.
xij ∈ {0, 1}, ∀i, j ∈ {1, . . . , n}.

 

Lors de la résolution de ce problème, il suffit de construire la matrice d’adjacence associé au graphe.

7) Écrire le modèle (P1 ) en langage GMPL, ensuite, Générer et résoudre une instance aléatoire de
taille n = 60.
Un couplage M est dit parfait si tous les sommets de G sont couverts (i.e., ∪u∈M u = V ). Voici un
exemple d’un couplage parfait d’un graphe de Petersen :

8) Écrire un modèle en langage CPLEX LP permettant de trouver un couplage parfait de taille


maximum du graphe Petersen.

4.4 Coloration de graphe (Graph coloring Problem)

Le problème de coloration de graphe consiste à assigner à chaque sommet une couleur, de façon à
ce que deux sommets adjacents soient de couleurs différentes. En d’autre termes, soit G = (V, E) un

16
graphe simple ; une coloration propre de G (à k couleur) est une application c : V → K associée au
sommets du graphe G, tel que : ∀ e = {u, v} ∈ Ec(u) 6= c(v), avec K = {1, . . . , k} est l’ensemble des
"couleurs". Le problème d’optimisation consiste à trouver une coloration propre en utilisant un nombre
minimum de couleur (noté χ(G)). Pour ce problème, on vous propose trois modèles différente : (P1 )
est un modèle mathématique intuitif. Afin de pouvoir l’écrire en langage informatique compatible à
GLPK, il est préférable de numériser les objets mathématiques (i.e., les ensembles V et E), et linéariser
la contrainte contenant la valeur absolu (résultant le PLNE (P3 )).

min Z = y,








 s.c.
xv ≤ y, ∀ v ∈ V,

(P1 )
|xv − xu | ≥ 1, ∀ {u, v} ∈ E,






xv ∈ N∗ , ∀ v ∈ V.




 Xn 
min Z = z,




 min Z(y) = yi , 



i=1 s.c.

 

 
s.c.

 

xi ≤ z, ∀i ∈ {1, . . . , n},

 


 n
X


 
xij = 1, ∀i ∈ {1, . . . , n},

 

(P2 ) (P3 ) aij (xi − xj ) ≤ n yij − 1, ∀i, j ∈ {1, . . . , n},
 j=1 
aij (xj − xi ) ≤ n (1 − yij ) − 1, ∀i, j ∈ {1, . . . , n},
 
xij ≤ yj , ∀i, j ∈ {1, . . . , n},

 


 

 
yij ∈ {0, 1}, ∀i, j ∈ {1, . . . , n}.

 




 aij (xik + xjk ) ≤ 1, ∀i, j ∈ {1, . . . , n}, 



xi ∈ N∗ , ∀i, j ∈ {1, . . . , n}.

 

xij , yj ∈ {0, 1}, ∀i, j ∈ {1, . . . , n}.

 

4.4.1 Exemple illustratif

On se donne l’exemple de graphe de Pretersen, la coloration optimale de ce graphe (Z ∗ = 3) est


la suivante :

9) Donner une description pour chaque modèle (en termes de dimension des variables de décision
et des données requise), et comparer les modèles en termes d’implémentation. Désigner le(s) mo-
dèle(s) adéquat à l’implémentation sous GLPK. Justifier votre réponse.
10) Écrire (P3 ) et (P3 ) en langage GMPL, ensuite, Générer et résoudre une instance aléatoire de
taille n = 30.

17
4.5 Problème de voyageur de commerce (Traveling Salesman Problem, TSP)

Son nom vient de la situation fictive suivante : étant donné une carte avec des villes, des chemins
et des distances (ou temps de trajet) entre ces villes, un voyageur de commerce cherche un itinéraire
réalisant la distance minimal qui passe par toutes les villes, et finalement, revient à la ville de départ,
sachant qu’il ne visite chaque ville qu’une fois. En langage mathématique, le problème consiste à
trouver un cycle hamiltonien de poids minimum un graphe donné, où les sommets sont des villes et
les arêtes sont des routes joignant les villes.

4.5.1 Exemple illustratif

Soit G = (V, E) un graphe complet à six sommets, on définit également des poids (" distances")
sur les arêtes qu’on peut la représenter par une matrice carrée d = (dij )1≤i≤n,1≤j≤n de diago-
nale null. Le cycle hamiltonien présenté en rouge est une solution réalisable de ce problème : S =
{(a, d)(d, f )(f, b)(b, c)(c, e)(e, a)}, on peut la représenter également sous forme d’une séquence (per-
mutation) de sommets : S = [a, d, f, b, c, e, a]. Le coût de la tournée S est de : 119.

10
2 6
35
28

13

3 13 5
20

4.5.2 Devoir ***


11) Proposer un modèle mathématique pour ce problème. Générer et résoudre à l’aide de GLPK
une instance aléatoire de taille 30.

A propos du TP
Ce document est destinée au étudiants en troisième année licence Recherche Opérationnelle de la
faculté de Mathématique, USTHB.
Les sources de ce TP sont sur le dépot :

github.com/nkantour/tpGLPK

18
Quelques références :

Sylvie Borne (2012), Optimisation et logiciels, https://lipn.univ-paris13.fr/~borne/Docs/


cm_ol.pdf.
Andrew Makhorin (2008). GLPK (GNU linear programming kit). https://www.gnu.org/software/
glpk/#TOCdocumentation.
Andrew Makhorin (2000), Modeling language gnu mathprog. Relatório Técnico, Moscow Aviation
Institute. http://www.cs.unb.ca/~bremner/docs/glpk/gmpl.pdf.
. . . (liste ref. incomplète)

19