Sunteți pe pagina 1din 9

OPTIMIZAREA PROBLEMELOR DE PROGRAMARE LINIARĂ PRIN METODA

SIMPLEX
OPTIMIZATION OF LINEAR PROGRAMMING PROBLEMS THROUGH THE
SIMPLEX METHOD

Liubomir CHIRIAC, dr. hab., prof. univ.


Universitatea de Stat din Tiraspol
Andrian DASCAL, professor la discipline de informatică
IP Centrul de Excelență în Informatică și Tehnologii Informaționale

Abstract: Articolul de față analizează rolul pe care îl are metoda simplex în soluționarea problemelor
de programare liniară. Principalele idei ale articolului se referă la importanța pe care o are metoda simplex
în rezolvarea problemelor de programare liniară din diverse domenii de activitate ale vieții cotidiene.
Abstract: This article analyzes the role of the simplex method in solving linear programming problems.
The main ideas of the article refer to the importance of the simplex method in solving linear programming
problems in various fields of daily life activity.

Cuvinte cheie: programare liniară, metoda SIMPLEX, algoritm, optimizare, pascal, maple etc.
Keywords: linear programming, SIMPLEX method, algorithm, optimization, pascal, maple, etc.

O gamă largă de probleme de programare liniară dețin multe variabile atunci când ne
propunem să-i găsim soluția, astfel metoda grafică de rezolvare a problemei respective nu poate fi
aplicată. Voi prezenta aplicabilitatea algoritmului Simplex în soluționarea unei varietăți de probleme
de programare liniară. Diverse aplicații industriale aplică algoritmul Simplex în soluționarea
problemelor de programare liniară cu mii de restricții și variabile.
Metoda Simplex a fost propusă în 1947 de George Dantzig pentru soluționarea problemelor
de programare liniară. Algoritmul permite o căutare prin mulțimea soluțiilor posibile pentru găsirea
soluției optime obiectivului propus.
De la dezvoltarea algoritmului simplex, programarea liniară este utilizată în toate domeniile
de la cel industrial, la cel bancar, educațional, forestier, petrolier, etc. conducând la soluționarea
unei mari varietăți de problem cum ar fi: stabilirea resurselor umane, operațiile sistemelor hidro-
energetice, traseele mașinilor de aprovizionare,etc.
Metoda Simplex a lui Danzing, cu unele modificări relativ minore, este cea mai importantă
metodă în găsirea soluțiilor problemelor de programare liniară. Implementarea algoritmului simplex
în practică, presupune parcurgerea următoarelor etape: standardizarea problemei; transformarea
formei standard în forma tabelară și efectuarea calculelor, transformărilor necesare prin aplicarea
metodei simplex. În activitatea de conducere, organizare și planificare se întâlnesc o serie de
probleme privind repartizarea resurselor (a unor cantităţi de la unităţile furnizoare la cele
consumatoare). Pentru elaborarea planului de transport intern la o întreprindere se pune problema de
a repartiza anumite cantităţi privind un anumit material de la depozite (furnizori) la unităţi de
producţie – secţii, ateliere (consumatori). Această repartizare trebuie făcută în aşa fel încât să se
asigure costuri minime de transport.
Metoda simplex este un proces iterativ de rezolvare directă a unui sistem de ecuații pas cu
pas, pornind de la soluția de referință și căutând cea mai bună opțiune, se deplasează de-a lungul
punctelor de colț ale regiunii unei soluții fezabile, îmbunătățind valoarea funcției obiectiv până când
funcția obiectivului atinge valoarea optimă.
Algoritmul metodei simplex
1. Întocmirea primului plan de referință. Tranziția la forma canonică a unei probleme de
programare liniară prin introducerea variabilelor de balanță suplimentare ne-negative.
2. Verificați planul pentru optimalitate. Dacă există cel puțin un coeficient de linie de index mai
mic decât zero, atunci planul nu este optim și trebuie îmbunătățit.
3. Identificați coloana și rândul principal. Din coeficienții negativi ai rândului index este
selectată cea mai mare din valoarea absolută. Apoi elementele coloanei membrilor liberi ai
tabelului simplex sunt împărțiți în elemente ale aceluiași semn al coloanei de conducere.
4. Construirea unui nou plan de referință. Trecerea la noul plan se efectuează ca urmare a
recalculării tabelului simplex prin metoda Jordan - Gauss.

Teorema principală a programării liniare (PL)


Dacă funcția obiectivă a PL atinge o valoare extremă într-un anumit punct din domeniul
soluțiilor fezabile, atunci această valoare este luată la un punct de colț. Dacă funcția obiectivă a PL
atinge o valoare extremă la mai mult de un punct de colț, atunci ea are aceeași valoare la oricare
dintre combinațiile liniare convexe ale acestor puncte.

Esența metodei simplex.


Mișcarea la punctul optim se realizează prin deplasarea de la un punct de colț la altul, ceea ce
aduce mai aproape și mai rapid la x optim. Punctele de colț sunt caracterizate prin variabile de bază
m, prin urmare, este posibilă trecerea de la un punct de colț la un punct învecinat prin schimbarea
unei singure variabile de bază la o variabilă dintr-o bază nonbasică în bază. Implementarea metodei
simplex datorită diferitelor caracteristici și formularea problemei de PL are diverse modificări.

În continuare vom descrie succint cele 3 etape ale metodei simplex:


1. Găsirea celei mai mari valori pozitive pentru cj - zj. Aceasta va desemna coloana pivot. Dacă
nu există o astfel de valoare, atunci soluția optimă a fost deja găsită.
2. Pentru fiecare valoare pozitivă din coloana pivot se găsește raportul: (membrul drept) /
(elementul corespunzător din coloana pivot). Raportul minim stabilește linia pivot. La
intersecția coloanei pivot cu linia pivot se găsește elementul pivot.
3. Se generează noua formă tabelară astfel:
b) Se împarte linia pivot la elementul pivot;
c) Pentru toate celelalte linii, se înmulțește noua linie generată la punctul (a). Prin elementul
corespunzător din coloana pivot și se extrage din linia curentă.
d) Se completează celulele taloului și se trece la pasul 1.

Remarca 1 :
 Pasul 1 al metodei simplex stabilește variabila cu cea mai mare influență unitară asupra
funcției obiectiv.
 Pasul al 2-lea stabilește care variabilă devine prima zero pe măsură ce crește variabila cu
influența cea mai mare.
 Pasul al 3-lea generează noul tablou cu variabila din pasul 1 înlocuind variabila stabilită la
pasul al 2-lea.

Remarca 2 :
 Dacă trebuie să găsim extrema funcției obiectiv, atunci vorbim despre găsirea valorii minime
(F (x) → min) și valoarea maximă (F (x) → max).
 Soluția extremă este atinsă la limita regiunii de soluții fezabile la unul din vârfurile punctelor
de colț ale poligonului sau la intervalul dintre două puncte de colț adiacente.

Remarca 3 :
 Procedura descrisă mai sus se aplică problemelor de maximizare. Pentru problemele de
minimizare putem proceda:
 multiplicând funcția obiectiv cu -1 și maximizând, sau
 schimbând pasul 1 astfel încât să se găsească cel mai negativ cj - zj și stop dacă nu a fost
găsită o astfel de valoare.

Metoda simplex primal, sau metoda îmbunătăţirilor succesive, evită cercetarea exhaustivă a
tuturor soluţiilor de bază ale unui model de (P.L.), construind succesiv soluţii realizabile de bază din
ce în ce mai bune ale modelului până când este obţinută o soluţie de bază optimă. Evident, prin
soluţie mai bună vom înţelege o soluţie care dă pentru funcţia de eficienţă o valoare mai mare,
respectiv mai mică decât cele precedente, după cum funcţia de eficienţă trebuie să devină maximă,
respectiv minimă. În descrierea şi justificarea metodei algoritmului simplex primal, ne vom referi
iniţial la un model de (P.L.) în care funcţia de eficienţă trebuie să devină maximă.

Rezolvarea problemei de transport


Este evident că problema de transport la forma standard este o problemă de programare
liniară la forma standard, la fel de evident este şi faptul că este o problemă de programare care
devine foarte repede uriaşă (un exemplu practic obişnuit cu, de exemplu, 50 de furnizori şi 50
consumatori, va duce la un tabel simplex de 100  2500, şi sunt cazuri şi cu mii de furnizori şi
consumatori), motiv pentru care algoritmul simplex sub forma clasică nu este aplicabil.
Există şi metode prin care se poate reduce mult volumul de calcule, pentru aceasta se aplică
algoritmul simplex revizuit. În plus, datele problemei de transport au o structură cu totul deosebită,
în matricea A a sistemului, toate componentele fiind 1 sau 0, din care 0 sunt mult mai mulţi. Din
acest motiv este natural să căutăm un algoritm special pentru problema de transport care să se
folosească la maximum caracteristicile acesteia.

Variante ale problemei de transport


Există o gamă foarte largă de fenomene economice care pot fi reprezentate prin modele de
programare liniară de tip transport sau foarte asemănătoare cu acestea. Prezintam în continuare
câteva dintre acestea:
a) Cu rute blocate.
b) Cu puncte intermediare.
c) Problema afectării.
d) Problema încărcării utilajelor.
e) Problema de transport a lui Koopmans.

Problemă rezolvată
Fie modelul de (P.L.): [max]f=2x1+x2+3x3+5x4+9x5
x1+2x3+x4+3x5=15
x2+x3+2x4+x5=12
xj≥0, j=1,2,3,4,5
Rezolvare :
Construind tabelul simplex vom găsi pornind de la soluţia de bază x1=15, x2=12, x3=x4=x5=0

CB B XB 2 1 3 5 9
a1 a2 a3 a4 a5
2 a1 15 1 0 2 1 3
1 a2 12 0 1 1 2 1
/ ∆i 42 0 0 -2 1 2
9 a5 5 1/3 0 2/3 1/3 1
1 a2 7 -1/3 1 1/3 5/3 0
/ ∆i 52 -2/3 0 -10/3 1/3 0
9 a5 18/5 2/5 -1/5 3/5 0 1
5 a4 21/5 -1/5 3/5 1/5 1 0
/ ∆i 267/5 -3/5 -1/5 -17/5 0 0

Algoritmul simplex a luat sfârşit, soluţia optimă fiind xopt=(0,0,0,21/5,18/5), căreia îi


corespunde f max=267/5.

Observaţie
 Criteriul de ieşire din bază, aşa cum am precizat mai înainte, cere ca vectorul care intră în
bază să conţină cel puţin o componentă pozitivă. Dacă din criteriul de optim rezultă că
soluţia nu este optimă şi vectorul care trebuie să intre în bază nu are nici o componentă
pozitivă, atunci problema nu admite optim finit (optimul este infinit).
 În cazul când în tabelul simplex optim avem diferenţe nule şi în dreptul altor vectori care nu
fac parte din baza optimă, problema admite soluţie optimă multiplă. Pentru a găsi şi alte
soluţii optime se continuă algoritmul simplex introducând în bază unul din vectorii din afara
bazei căruia îi aparţine o diferenţă nulă.

Problemă rezolvată

Fie următoarea problemă de programare liniară: z = 2x 1 + 3x 2 + 4x 3 → MAX


x 1 + x 2 + x 3 ≤ 30
2x 1 + x 2 + 3x 3 ≥ 60
x 1 – x 2 + 2x 3 = 20
x j ≥ 0, j=1,2,3

Rezolvare :

Implementarea metodei SIMPLEX în Maple 18

Funcția LPSolve permite rezolvarea problemelor de programare liniară (LP), care implică
calcularea valorilor minime (sau maxime) ale unei funcții obiective liniare supuse unor constrângeri
liniare. Se pot rezolva LP-uri continue, întregi, intregi mixte și binare.
LPSolve recunoaște, de asemenea, problema în forma Matrix. Formularul matricei conduce
la un calcul mai eficient, dar este mai complex. LPSolve utilizează fie o metodă activă, fie o metodă
de punct interior.
Legaturile pentru una sau mai multe variabile sunt date ca argumente suplimentare, fiecare
dintre formulele varname = varrange unde varname este un nume de variabilă și varrange este
intervalul său. Obiectivele de domeniu pot include, în general, valori de tip infinit. Pentru metoda
punctului interior, totuși, limitele inferioare trebuie să fie finite. Non-negativitatea variabilelor din
problemă nu este asumată implicit, dar poate fi specificată cu opțiunea assume = nonnegative.
Maple returnează soluția ca o listă care conține valoarea minimă finală (sau maximă) și un punct
(extremum). Dacă este furnizată opțiunea output = solutionmodule, atunci un modul este returnat.
Consultați pagina de ajutor Optimizare / soluție pentru mai multe informații. Dacă aveți nevoie doar
de un punct fezabil pentru problemă, utilizați 0 ca primul argument pentru LPSolve urmat de
constrângeri și / sau limite.
Comanda Optimizare [ImportMPS] poate fi utilizată pentru a importa fișiere de date MPS (X).
Această comandă returnează o reprezentare combinată Matrix și Vector a LP care poate fi trimisă
comenzii LPSolve utilizând forma de intrare Matrix. Pentru mai multe informații, consultați pagina
de ajutor LPSolve (Matrix Form).

Rezolvare problemei cu ajutorul softului Maple se realizează prin apelarea secvenței:


LPSolve (obj, constr, bd, opts).

 Primul parametru obj este funcția obiectivă, care trebuie să fie o expresie algebrică liniară.
 Al doilea parametru constr este opțional și este un set sau o listă de relații (de tip `<=` sau `=`),
liniară în variabilele de problemă. Variabilele de problemă sunt indeterminate de tipul de nume
găsit în obj și constr. Acestea pot fi de asemenea specificate utilizând opțiunea variabilelor.

>
>

Implementarea metodei SIMPLEX în limbajul PASCAL

Program Test_Simplex;
Uses Crt;
Label 3;
Const MMAX=50; NMAX=50;
Type MATRICE = Array[1..MMAX,1..NMAX] of REAL;
VECTOR = Array[1..MMAX] of Integer;
Var A,B: MATRICE;
IPOSV, IZROV: VECTOR;
i,j,CAZUL,N,M,M1,M2,M3: Integer;
R: REAL;
Procedure simplex1(var a:MATRICE; mm:integer; ll:VECTOR; nll, iabf: integer; var kp:
integer;
var bmax:REAL); Forward;
Procedure simplex2(var a:MATRICE; m, n:integer; l2:VECTOR; nl2:integer; var ip:integer;
kp:integer; var q1:REAL); Forward;
Procedure simplex3(var a:MATRICE; i1,k1,ip,kp:integer); Forward;
Procedure Maxsimplex(var a:MATRICE; m, n, m1, m2, m3: Integer; var icase:Integer; var
izrov, iposv:VECTOR);
Label 1,2,3,4,5, return;
Var i,ip,ir,k,kh,kp,m12,nl1,nl2: Integer; ks: Integer;
l1, l2, l3: VECTOR; bmax,q1,EPS: REAL;
Begin
EPS:=1e-6;
if m <> m1+m2+m3 then
begin
writeln(' Constrangere insuficienta de contorizare pentru simplx.');
goto return
end;
nl1:=n;
for k:=1 to n do
begin
l1[k]:=k; { Inițializăm lista de indexuri a coloanelor admise pentru schimb.}
izrov[k]:=k { Transferăm inițial toate variabilele la dreapta.}
end;
nl2:=m;
for i:=1 to m do
begin
if a[i+1,1] < 0.0 then
begin
writeln(' Tablou de intrare gresit in simplex, constantele bi trebuie să fie
nonnegative.');
goto return
end;
l2[i]:=i; iposv[i]:=n+i
end;
for i:=1 to m2 do l3[i]:=1;
ir:=0;
if m2+m3 = 0 then goto 5; { Originea este o soluție de pornire fezabilă. Trecem la
faza a doua.}
ir:=1;
for k:=1 to n+1 do { Calculăm funcția obiectivului auxiliar.}
begin
q1:=0.0;
for i:=m1+1 to m do q1 := q1 + a[i+1,k];
a[m+2,k]:=-q1
end;
3: simplex1(a,m+1,l1,nl1,0,kp,bmax); { Găsim coef. max. din obiectivul auxiliar
fn }
if(bmax <= EPS) and (a[m+2,1] < -EPS) then
begin
icase:=-1; { Funcția obiectivului auxiliar este incă negativă și nu poate fi
imbunătățită, prin urmare nu există o soluție fezabilă}
goto return
end
else if (bmax <= EPS) and (a[m+2,1] <= EPS) then
begin
m12:=m1+m2+1;
if m12 <= m then
for ip:=m12 to m do
if iposv[ip] = ip+n then {Găsim o variabilă artificială pentru o restricție
de egalitate.}
begin
simplex1(a,ip,l1,nl1,1,kp,bmax);
if bmax > EPS then goto 1; {Schimbăm cu coloana corespunzătoare elementul
pivot maxim in rand.}
end;
ir:=0;
m12:=m12-1;
if m1+1 > m12 then goto 5;
for i:=m1+1 to m1+m2 do { Schimbăm semnul randului pentru orice constrangere
m2 incă prezentă din baza inițială.}
if l3[i-m1] = 1 then
for k:=1 to n+1 do
a[i+1,k] := -1.0 * a[i+1,k];
goto 5; {Trecem la faza a doua.}
end;
simplex2(a,m,n,l2,nl2,ip,kp,q1); {Localizăm un element pivot (prima fază). }
if ip = 0 then {Funcția maximă a obiectivului auxiliar este neingrădită,
deci nu există o soluție fezabilă.}
begin
icase:=-1;
goto return
end;
1: simplex3(a,m+1,n,ip,kp);
{Schimbăm o variabilă stangă și dreaptă (prima fază), apoi actualizăm listele.}
if iposv[ip] >= n+m1+m2+1 then
{Schimbarea unei variabile artificiale pentru o constrangere egală. Ne asigurăm că rămane
in afară, eliminand-o din lista l1. }
begin
for k:=1 to nl1 do
if l1[k] = kp then goto 2;
2: nl1:=nl1-1;
for ks:=k to nl1 do l1[ks]:=l1[ks+1];
end
else
begin
if iposv[ip] < n+m1+1 then goto 4;
kh:=iposv[ip]-m1-n;
if l3[kh] = 0 then goto 4; {Schimbarea constrangerii de tip m2.}
l3[kh]:=0
{Dacă este pentru prima dată, corectăm coloana pivot sau semnul minus și variabila
artificială implicită.}
end;
a[m+2,kp+1] := a[m+2,kp+1] + 1.0;
for i:=1 to m+2 do a[i,kp+1] := -1.0 * a[i,kp+1];
4: ks:=izrov[kp]; {Actualizăm listele de variabile stanga și dreapta.}
izrov[kp]:=iposv[ip];
iposv[ip]:=ks;
if ir <> 0 then goto 3;
{ Dacă este incă in prima fază, revenim la 10. Sfarșitul primului cod de fază pentru
găsirea unei soluții inițiale fezabile. In faza a doua, il optimizăm.}
5: simplex1(a,0,l1,nl1,0,kp,bmax); {Testul z-rand pentru marcare.}
if bmax <= EPS then {Terminat. Soluție găsită. Ne intoarcem cu vestea bună.}
begin
icase:=0;
goto return
end;
simplex2(a,m,n,l2,nl2,ip,kp,q1); {Localizăm un element pivot (faza a doua).}
if ip = 0 then {Funcția obiectiv este nelimitată. Raportăm și revenim.}
begin
icase:=1;
goto return
end;
simplex3(a,m,n,ip,kp);
{Schimbăm o variabilă stanga și dreapta (faza a doua),actualizăm listele de variabile
stanga și dreapta, apoi revenim pentru o altă iterație. }
goto 4;
return: End;
{Rutina precedentă (codul anterior)utilizează următoarele subrutine (secvențe de cod):}
//******************************************************************************
Procedure simplex1(var a:MATRICE; mm:integer; ll:VECTOR; nll, iabf: integer; var kp:
integer;var bmax:REAL);
{Determinăm valoarea maximă a acelor elemente al căror indice este conținut in lista
furnizată ll, fie cu sau fără a lua valoarea absolută, așa cum este marcată de iabf. }
Label return;
Var k: integer; test: REAL;
Begin
kp:=ll[1];
bmax:=a[mm+1,kp+1];
if nll < 2 then goto return;
for k:=2 to nll do
begin
if iabf = 0 then
test:=a[mm+1,ll[k]+1]-bmax
else
test:=abs(a[mm+1,ll[k]+1])-abs(bmax);
if test > 0.0 then
begin
bmax:=a[mm+1,ll[k]+1]; kp:=ll[k]
end
end;
return: End;
//******************************************************************************
Procedure simplex2(var a:MATRICE; m, n:integer; l2:VECTOR; nl2:integer;
var ip:integer; kp:integer; var q1:REAL);
Label 2,6, return;
Var EPS: REAL; i,ii,k: integer; q,q0,qp: REAL;
Begin
EPS:=1e-6; { Localizăm un element pivot, ținand cont de degenerare.}
ip:=0;
if nl2 < 1 then goto return;
for i:=1 to nl2 do
if a[i+1,kp+1] < -EPS then goto 2;
goto return; {Nu sunt posibile elemente pivoț.}
2: q1:=-a[l2[i]+1,1]/a[l2[i]+1,kp+1];
ip:=l2[i];
if i+1 > nl2 then goto return;
for i:=i+1 to nl2 do
begin
ii:=l2[i];
if a[ii+1,kp+1] < -EPS then
begin
q:=-a[ii+1,1]/a[ii+1,kp+1];
if q < q1 then
begin
ip:=ii; q1:=q
end
else if q = q1 then {Avem o degenerare.}
begin
for k:=1 to n do
begin
qp:=-a[ip+1,k+1]/a[ip+1,kp+1];
q0:=-a[ii+1,k+1]/a[ii+1,kp+1];
if q0 <> qp then goto 6
end;
6: if q0 < qp then ip:=ii
end
end
end;
return: End;
//******************************************************************************
Procedure simplex3(var a:MATRICE; i1,k1,ip,kp:integer);
{Operațiuni cu matrici pentru a schimba o variabilă din s tanga și din dreapta.}
Var ii,kk:integer; piv:REAL;
Begin
piv:=1.0/a[ip+1,kp+1];
if i1 >= 0 then
for ii:=1 to i1+1 do
begin
if ii-1 <> ip then
begin
a[ii,kp+1] := a[ii,kp+1] * piv;
for kk:=1 to k1+1 do
if kk-1 <> kp then
a[ii,kk] := a[ii,kk] - a[ip+1,kk]*a[ii,kp+1]
end
end;
for kk:=1 to k1+1 do
if kk-1 <> kp then a[ip+1,kk] :=-a[ip+1,kk]*piv;
a[ip+1,kp+1]:=piv
End;
//******************************************************************************
BEGIN
writeln;
write(' Introdu numarul de variabile ale problemei de programare liniara: ' );
readln(N);
write(' Introdu numarul de inegalitati "<=" : ' ); readln(M1);
write(' Introdu numarul de inegalitati ">=" : ' ); readln(M2);
write(' Introdu numarul de egalitati " =" : ' ); readln(M3);
M:=M1+M2+M3; {Total number of constraints}
for i:=1 to M+2 do
for j:=1 to N+1 do
A[i,j]:=0.0;
writeln(' Introdu functia economica de cercetare:');
for i:=2 to N+1 do
begin
write(' *A* ',i-1,': '); readln(A[1,i])
end;
write(' Introdu termenii constanti : '); readln(A[1,1]); {constrangeri de intrare,
A[1,1]=0.}
B[1,1]:=A[1,1];
for i:=1 to M do
begin
writeln(' Ecuatia ',i,':');
for j:=2 to N+1 do
begin
write(' *C* ',j-1,': '); readln(R);
A[i+1,j] := -R
end;
write(' Termenul constant: '); readln(A[i+1,1])
end;
CLRSCR;
writeln; writeln(' Tabelul initial obtinut:');
for i:=1 to M+1 do
begin
for j:=1 to N+1 do write(A[i,j]:8:2);
writeln
end;
Maxsimplex(A,M,N,M1,M2,M3,CAZUL,IZROV,IPOSV);
if CAZUL=0 then {Rezultat bun.}
begin
writeln;
writeln(' Solutia problemei va obtine valoarea maxima = ' , (A[1,1]-B[1,1]):12:6);
for i:=1 to N do
begin
for j:=1 to M do
if IPOSV[j] = i then
begin
writeln(' X',i,' = ', A[j+1,1]:12:6);
goto 3;
end;
writeln(' X',i,' = ', 0.0:12:6);
3: end
end
else writeln(' Nu avem solutie in acest caz, (error code = ' , CAZUL,').'); writeln;
ReadKey;
END.

Soluția poate fi verificată online : http://simplex.tode.cz/en/sg3sxmiyiyj

S-ar putea să vă placă și