Vous êtes sur la page 1sur 29

UNIVERSITE SIDI MOHAMED BEN ABDALLAH

ECOLE NATIONALE DES SCIENCES APPLIQUEES

PROGRAMATION LINEAIRE
METHODE DES DEUX PHASES

LE RAPPORT EST :
Réalisé par : Encadré par :
LINA LYOUSSI Pr.SAFAE EL HAJ BENALI

MEHDI LAOUINA

AHMED SEMLALI

CHAIMAE HDIDI

Année universitaire 2021/2022


INTRODUCTION :
Lors de la manipulation d’un problème linéaire, le cas le plus
simple est quand les contraintes ont le signe <= . Dans ce cas la
méthode de simplexe est directement applicable pour trouver
une solution, en partant de la solution initiale qui est la solution
nulle.

Alors que souvent dans les problèmes du monde réel, on


retrouve des contraintes de type mixtes = et >=. Dans ce cas la
solution initiale qui va nous servir comme point de départ de
l’algorithme de simplexe n’est pas triviale, d’où l’intérêt de la
méthode des deux phases, la première phase vise à trouver une
solution initiale pour la deuxième phase qui est exactement les
étapes de l’algorithme de simplexe.

Dans ce rapport nous allons traiter sous MATLAB :

❖ La représentation graphique d’un PL sous forme d’un


domaine réalisable pour les contraintes de type >=, <= et =.
❖ L’implémentation et l’explication en détail des codes des
fonctions pour trouver un max ou min d’un PL à l’aide de la
méthode des deux phases.
❖ Le test d’algorithme à travers des exemples irréguliers.
L’organigramme suivant décrit les étapes nécessaires à la résolution d’un
PL pour les deux phases :

Y’a-t-il des
contraintes de
Non types >= ou = ?
Oui

Méthode simplexe Méthode deux phases

Tableau initial
Mettre en place le premier tableau
pour minimiser la somme des
variables artificielles

oui
Condition sur les couts
réduits ?

non oui
Condition sur les couts
réduits ?
Choix de variable
entrante
non

Choix de variable
Choix de variable
entrante
sortante

Choix de variable
Mise à jour du tableau sortante

Mise à jour du tableau

Fonction non
oui objectif=0 ?
Retour du résultat

Supprimer les pas de


colonnes des solution
var.artifi.
1. Domaine réalisable
La fonction Domaine réalisable reçoit en paramètre :

DomaineRealisable(A,b,c,H)

A : la matrice des coefficients des variables dans les contraintes.


b : les éléments du second membre b.
c : le vecteur de la fonction objective.
H : c’est un vecteur contenant les signes de comparaison de chaque
contrainte de telle sorte que :
≥ est représenté par 1
≤ est représenté par -1
= est représenté par 0

Exemple :
3x1 + 2x2 ≥ 18
x1 + 3x2 ≤ 12
x1 + x2 = 8
L’appel a la fonction sera sous la forme :

DomaineRealisable(A,b,c,[1 -1 0])

✔ On se base dans la réalisation de la fonction du domaine réalisable


sur la fonction polyshape qui permet de créer des polygones en
passons 3 points ou plus comme paramètres :

Polyshape(X,Y)
Avec X=[x1 x2 x3 …]
Et Y=[y1 y2 y3 …]
✔ Donc on doit évaluer chaque contrainte pour choisir les bons points
qui nous permet de tracer le demi plan délimité par la contrainte sur
quadrant positif du plan cartésien (x≥0 y≥0).

✔ Puisque on ne peut pas afficher l’infini ou plus précisément un


polygone non borné on a pris 10^6 comme un représentant d’un x
ou y non borne ou les deux à la fois.

Dans la discussion des cas on a trouvé que les éléments suivants


affectent les points qu’on doit passer à polyshape :
● Le coefficient de la 1ère et 2ème variable.
● Le signe de comparaison.
● Le second membre b.

D’où on a traité ces cas selon l’ordre

b : positif ou nul (bnull.m et bpositif.m)

Les coefficients de variables : positif négatif ou nul

Le signe de comparaison : supérieur inferieur ou égal

Dans ce qui suit on a démontré comment on choisit les points pour


construire le polygone représentant de chaque contrainte ainsi que les
formules correspondantes.
𝐴1 𝑥1 + 𝐴2 𝑥2 ≤ 𝑏 𝐴1 𝑥1 + 𝐴2 𝑥2 ≥ 𝑏
Avec A1, A2, b≥0
Exemples : x1+x2≤5 x1+x2≥5

Px=[0 0 b/A(1)] Px=[0 0 10e6 10e6 b/A(1)]


Py=[0 b/A(2) 0] Py=[b/A(2) 10e6 10e6 0 0 ]

𝐴1 𝑥1 + 𝐴2 𝑥2 ≤ 𝑏 𝐴1 𝑥1 + 𝐴2 𝑥2 ≥ 𝑏
Avec A1, b≥0 et A2≤0
Exemples : x1-x2≤5 x1-
x2≥5

Px=[0 b/A(1) (-
10e6*A(2)+b)/A(1) 0] Px=[b/A(1) 10e6 10e6 ]
Py=[0 0 10e6 10e6] Py=[0 0 (10e6*A(1)-b)/A(2)]
𝐴1 𝑥1 + 𝐴2 𝑥2 ≤ 𝑏 𝐴1 𝑥1 + 𝐴2 𝑥2 ≥ 𝑏
Avec A2, b≥0 et A1≤0
Exemples : x1-x2≤5 x1-x2≥5

Px=[0 0 10e6 10e6] Px=[0 0 b+A(2)*10e6 /A(2)]


Py=[0 b/A(2) (b-A(1)*10e6)/A(2) 0] Py=[b/A(2) 10e6 10e6]

𝐴1 𝑥1 ≤ 𝑏 𝐴1 𝑥1 ≥ 𝑏
Avec A1, b≥0 et A2=0
Exemples: x1 ≤5 x1 ≥5

Px=[0 0 b/A(1) b/A(1)] Px=[b/A(1) b/A(1) 10e6 10e6]


Py=[0 10e6 10e6 0 ] Py=[ 0 10e6 10e6 0 ]
𝐴2 𝑥2 ≤ 𝑏 𝐴2 𝑥2 ≥ 𝑏
Avec A2,b≥0 et A1=0
Exemples: x2≤5 x2≥5

Px=[0 0 10e6 10e6]


Py=[0 b/A(2) b/A(2) 0]

Px=[0 0 10e6 10e6]


Py=[b/A(2) 10e6 10e6 b/A(2)]

Les cas non affiches dans cette démonstration sont :


⮚ Contrainte vérifié (le polygone contenant le quadrant positif du
plan cartésien).
⮚ Contrainte non vérifiée dans le domaine positif (le polygone
vide)
⮚ Autres cas comme b=0
▪ Par exemple pour x1-x2≤0 on va prendre 3 points au
lieu de 4.

On stocke les polygones des contraintes dans un tableau pour effectuer


l’intersection par la suite
L’étape suivante est de faire l’intersection des polygones pour avoir le
domaine réalisable :

La fonction intersect effectue cette tache en passant deux polygones en


paramètres et le résultat sera l’intersection d’eux.
Exemple :

L’intersection des ces deux polygone avec intersect() donne :

On boucle tout simplement sur les polygones jusqu’on obtient


l’intersection totale.
● Cas d’une contrainte de type égal =
Une contrainte de type égal signifie que le domaine réalisable n’est plus
une surface mais plutôt une demi droite.
Pour représenter une demi droite on construit deux vecteur X et Y qui
contient les coordonnes de 2 points qui nous permette de la tracer.
Mais avant on a besoin de faire l’intersection de cette demie droite
avec le polygone résultat des autres contraintes de type supérieur ou
inférieur.

Finalement, on fait l’intersection de notre demi droite et le polygone


résultat puis on affiche notre domaine réalisable.
Note : On peut avoir une demi droite ou un segment.

2. Méthode tabulaire Simplexe :


-La deuxième partie qu’on va entamer, consiste à programmer la
méthode tabulaire de l’algorithme du Simplexe : Le programme
linéaire qu’on va implémenter s’écrit de la forme :
Min c*x Max c*x
s.t s.t
A*x <= b Ou A*x <= b
A*x >= b A*x >= b
A*x = b A*x = b
x >= 0 x >= 0

🡪Que ça soit un problème de maximisation ou de minimisation, en


prenant en considération la méthode des deux phases lors de
l’existence d’une ou plusieurs contraintes de type >= ou =.
-La fonction principale est : « twoPhasesSimpAlgo.m »
-La fonction principale reçoit comme entrées une chaine de caractères
« String Str » qui porte une parmi deux valeurs : {« Min » ; « Max »}, la
matrice des contraintes A, le second membre b, la fonction objective c
et le vecteur signe « VectSigne » de tel sorte chaque contrainte de
type :
≥ est représenté par -1
≤ est représenté par 1
= est représenté par 0

-cette fonction principale contient deux sous fonctions « phase1 » et


« phase2 ».
🡪Phase1 qu’on passe comme des entrées A, b, c et VectSigne, et
donne comme des sorties une matrice « M » : le dernier tableau
normalisé de la première phase, et « BV » : la base optimale de la
première phase.
🡪Phase2 qu’on passe comme des entrées Str, M et BV.

I. Phase une “1”:


-En premier lieu, on va vérifier le signe des éléments de b, si un élément
est négatif, on le multiplie par -1, et aussi la contrainte correspondante
dans A et l’élément correspondant dans VectSigne, pour conserver
l’équilibre de nos entrées.

-En deuxième lieu, on crée les variables d’écart convenables, et les


variables artificielles si nous devons les créer ;
🡪D’abord, on crée « var_Ecart » : une matrice identité de taille n, et un
vecteur « indexVarArtf » ayant les indices où on a les contraintes de
type >= ou =,
🡪Puis, On boucle pour créer la matrice table initiale du Simplexe tout en
respectant le type de contrainte correspondante de sorte que :
🡪Cas où contrainte « <= » c-à-d VectSigne(i) == 1 : on ajoute à M
une colonne correspondante de la matrice identité, et l’indice de cette
colonne à BV.
🡪Cas où contrainte « >= » c-à-d VectSigne(i) == -1 : on ajoute à M
une colonne correspondante de la matrice identité mais de signe
négatif, et l’indice de sa variable artificielle correspondante à BV.
🡪 Cas où contrainte « = » c-à-d VectSigne(i) == 0 : on ajoute juste
l’indice de la variable artificielle de cette contrainte à BV.
🡪Ensuite, on initialise la dernière ligne de M par les couts réduits
initiales.
-Cette partie est effective pour les deux phases, car même si au cas
d’un problème qui ne consiste pas d’entamer la phase1, cette partie va
s’exécuter comme une initialisation de M et la base initiale.
-Après :

-le reste de cette fonction va être encadrée par cette condition « if


any(BV>n+m ) », cela veut dire que : si au moins un élément de la base
initiale contient une variable artificielle , on va exécuter la phase 1
🡪D’abord, on va modifier M, en ajoutant les variables artificielles,
et modifiant le type de problème qui sera de type minimisation des
variables artificielles, c-à-d on va changer aussi la fonction objective qui
va être la somme de ces variables artificielles.

🡪Ensuite, on affiche le tableau initial ainsi que la base initiale, puis


on normalise le tableau en modifiant la dernière ligne de « M », par la
somme des variables artificielles en fonction des variables hors base.
-l’étape suivante s’agit des multiples sous étapes ou bien des itérations
pour éliminer ou les variables artificielles.
🡪Premièrement :
Choisissant la variable entrante par la fonction « Var_Ent_phase1 » :

-On cherche le minimum des éléments se trouvant dans la dernière


ligne,
🡪Mais : si ce minimum est 0 différemment des couts réduits des
variables de base.
🡪On va chercher une variable entrante de sorte qu’une variable
artificielle (s’elle existe) doit sortir, sinon on arrête l’algorithme.
🡪Deuxièmement :
Choisissant la variable sortante :

-on vérifie si une variable artificielle a une valeur négative, car si oui 🡪
ce programme linéaire est non réalisable.
-On prend la variable « pivotColumnIndex » qui nous a pris a partir de la
variable entrante et on va calculer depuis M (:, pivotColumnIndex ), « le
ratio » correspondant et prenant le minimum positif pour la variable
sortante, mais cela en vérifiant :
🡪Cas où le PL est non borné : si le maximum de la colonne de la variable
entrante est égal à 0, cela veut dire que la variable correspondante
tend vers l’infinie.
🡪Cas où le PL est inadmissible : si tous les éléments de cette colonne
sont négatifs.

🡪Troisièmement :
-Revenant à la fonction « phase1 » :

Figure X
-Après, on va changer la base, ainsi que le tableau :

-Fonction « changement_de_base » qui prend en entrées : la base à


changer, l’indice de la variable entrante et l’indice de la variable
sortante.

-Fonction « Next_iteration » qui prend en entrées : la matrice tableau à


changer et les deux dernières entrées de la fonction
« changement_de_base »
🡪 Cette fonction fait en généralement les
opérations élémentaires après chaque itération, et cela se définit
comme suit :
🡺 Divisant la ligne de la variable sortante par le pivot
« M (pivotColumnIndex, pivotRowIndex) ».
🡺 Substituant chaque ligne Li de M par la ligne de pivot * le pivot
correspondant à Li.
🡺 Substituant la fonction objective « c » du problème intaille
comme l’illustrant dans « Figure X » précédente.
-La Condition qui suit « if all (BV <= n+m) » veut dire qu’on a bien
éliminer les variables artificielles, et on peut achever notre fonction
principale.
-La condition qui suit ensuite veut dire que notre problème ne peut se
réaliser et ne peut pas faire sortir les variables artificielles.

🡪Quatrièmement :
Revenant à la fonction « phase1 » :
-La dernière étape est d’éliminer les variables artificielles du Tableau Du
Simplexe, et par cela on va achever la première phase.

II. Phase deux “2”:

-On passe à la fonction « phase2 » comme entrées : la chaine « str »


indiquant le type du PL, {le dernier tableau M du phase 1 ou le tableau
initial sans variables artificielles}, et la base initiale du phase2.
🡪On commence par une boucle sous la condition d’optimalité
« isOptimal » :
🡪On définit les variables entrante et sortante par les fonctions
« Var_Ent » et « Var_Sort » (respectivement).
🡪Ensuite, on change de base, et modifie le tableau jusqu’on trouve la
solution optimale ou en rencontrant une erreur de réalisation.

-On achève par démontrant la solution au cas où on a une solution


optimale par la fonction « showSolution » :
III. Application:
-Prenant Ce Programme linéaire suivant :

-En le réalisant par notre fonction « twoPhasesSimpAlgo » :


Application sur un exemples :

Cas impossible:

Max 4x1+3x2

St x1+x2<=2

3x1+x2>=10

x1,x2>=0

ce cas qui n’admet pas de solution ,se traduit dans le fait que dans la base dans la phase 1
reste les variables artificielles, ce cas est détecté si le problème a dépassé un nombre
d’itération, lorsque on applique ce code sur notre fonction on constate que après certaines
itérations le nombre les variables de bases restent les mêmes, donc on a pas une solution
Jusqu’à l’itération 19
Le message d’erreur s’affiche :

Vous aimerez peut-être aussi