Sunteți pe pagina 1din 11

Universitatea Bucuresti

Facultatea de Matematica-Informatica
Specializarea Tehnologia Informatiei

ALGORITMUL
SIMPLEX

Jerca Vlad
anul I gr. 152

Cuprins

1. Definitie.......................................................................................................... 3
2. Exemple......................................................................................................... 4
3. Codarea in limbajul C...................................................................................... 6
4. Executarea programului................................................................................ 10

1. Definitie
A. Formulare

max f(x1...xn) = <c,x>

fj(x1...xn) bj
x1,...,xn 0
f
fj
xi

- functia obiectiv
- restrictiile problemei
- nivele la care se desfasoara activitatea

Daca f si fj ( j = 1,m ) sunt forme liniare se obtin probleme de programare liniara:



n
f(x) = i=1
cixi = <c,x>
Daca vectorii ai1,ai2,...,aim apartin Rm formeaza o baza B a lui Rm spunem ca variabilele xi1,xi2,...,xim
sunt variabile bazice (celelalte fiind nebazice).

Notam XB = B-1 * b

Daca XB 0 spunem ca B este baza primal admisibila. In acest caz notam:



I
= { i1,...,im }
CB
= { ci1,ci2,...,cim }
fB
= CB XB
fj
= CB aj

B. TABELUL SIMPLEX:

CB B XB
ci1
ci2

ai1
ai2

xi1
xi2

aie

xie

aim

a1 a 2 .................. a m .................. a j .................. a n

B-1 A

cie

cim

c1 c2 .................. cm .................. cj .................. cn

xim
fB
Cj-fj

f1

f 2 ..................

fm

..................

fj

.................. f n

c1-f1 c2-f2 ............... cm-fm ............... cj-fj ............... cn-fn

Se aplica testul de optimalitate asupra solutiei curente XB care consta in urmatoarea rezolvare:
a) Daca pentru orice j apartie lui J, cj - fj 0 problema are oftim finit, XB solutie optima si max f = fB
.

b) Daca pentru orice j apartie lui J, cj - fj > 0 atunci:



b1) daca coloana aj are toate elementele 0 problema nu are optim finit
b2) daca pe coloana aj exista cel putin un element > 0 atunci solutia curenta se poate
imbunatati conducand-o spre o solutie optima astfel:
- se determina indicele k al vectorului care intra in baza cu urmatoarea formula:
Ck-fk = max { cj - fj | oricare j apartie lui J pentru care cj - fj > 0 }
- se determina indicele l al vectorului care iese din baza B dupa formula:

x
aik

xil il

= min {

xij
ajk | oricare j apartine lui I pentru care ajk > 0 }

2. Exemple:
a) max f = 3x1 + 4x2 + 1x3

1x1 + 2x2 + 3x3 10


1x1 - 1x2 + 0x3 3
1x1 + 0x2 + 2x3 6

CB

XB

a1

a2

a3

a4

a5

a6

a4

10

a5

-1

a6

a2

1/2

3/2

1/2

a5

3/2

3/2

1/2

a6

20

-5

-2

a2

7/3

1/3

-1/3

a1

16/3

1/3

2/3

a6

2/3

-1/3

-2/3

76/3

7/3

2/3

-6

-7/3

-2/3

b) max f = 107x4 + 1x5 + 2x6

14/3x4 + 1/3x5 - 1/3x6 7/3


16x4 - 1/2x5 -2x6
5
3x4 + 0x5 + 0x6 0

107

CB

XB

a1

a2

a3

a4

a5

a6

a4

7/3

14/3

1/3

-1/3

a5

16

1/2

-2

a6

107

a4

7/3

-14/9

1/3

-1/3

a5

-16/3

1/2

-2

107

a1

1/3

107/3

107

-107/3

3. Codarea in limbajul C
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
//intarzie
void timp(int n)
{
for(int t=1;t<=n*100000;t++);
}
void afisez(char c[])
{
int i=0;
while(c[i])
{

putchar(c[i]);

timp(75);

i++;
}
}
//face pasul pentru inversa matricii
void pas(float a[255][255], int n,int n1, int poz1, int poz2)
{
int i, j;
float pivot;
pivot=a[poz1][poz2];


for(i=1;i<=n1;i++)
if(i!=poz1)

for(j=0 ;j <= n+n1; j++)
if(pivot!=0&&j!=poz2)
a[i][j]=a[i][j]-(a[poz1][j]*a[i][poz2])/pivot; // are loc
pasul

for (i=0 ; i <= n+n1; i++)

if(pivot!=0)

a[poz1][i]=a[poz1][i]/pivot; // impartim linia pivotului la pivot

for(i=1; i <= n1; i++)

if(i!=poz1)

a[i][poz2]=0; // elementele pe coloana pivotului iau valoarea 0

}
//calculeaza produsul scalar
void produsScalar(float a[255][255], float c[255], float f[255], int n,int n1)
{
for(int j=0;j<=n+n1;j++)
{

f[j]=0;

for(int i=0;i<=n;i++)
f[j]=f[j]+(a[i][j]*c[i]);
}
}

//citeste datele de intrare


void incarcDate(float a[255][255], float c[255], int b[255], int n,int n1)
{
int i, j;
// afisez forma max f
printf(max f = );
for(i=1;i<=n;i++)

{
printf(c%dx%d,i, i);
if(i!=n)
printf( + );
else printf(\n);

}
// afisez forma ecuatiilor
for(i=1;i<=n1;i++)

for(j=1;j<=n;j++)
{

printf(a%d%dx%d,i, j, j);
if(j!=n)
printf( + );

else printf( <= b%d\n, i);
}
// citesc max f
for( j=1; j<=n; j++)
{

printf(c%d = \t, j);

scanf(%f, &a[0][j]);
}
// citesc ecuatiile
for(i=1;i<=n1;i++)
{

for(j=1;j<=n;j++)
{
printf(a%d%d = \t,i,j);
scanf(%f, &a[i][j]);
}

printf(b%d = \t, i);

scanf(%f, &a[i][0]);
}
for(i=1;i<=n1;i++)

for(j=n+1;j<=n+n1;j++)

{
if(i+n==j)
a[i][j]=1;

}

// incarc vectorul C(B)

for(i=1;i<=n;i++)
c[i]=a[0][i+n];

//incarc vectorul B

for(i=1;i<=n1;i++)
b[i]=i+n;

}

//afiseaza tabelul simplex


void afisezTabel(float a[255][255], float c[255], float f[255], int b[255], int n,int n1)
{
system(cls);
printf(\n\t\t\t);
for(int i=1;i<=n+n1;i++)

printf(%.2f\t, a[0][i]);
printf(\nC(B)\t B\tX(B)\t);
for(int i=1;i<=n+n1;i++)

printf( a%d\t, i);
printf(\n\n);
for(int i=1;i<=n1;i++)

{

printf(%.2f\ta%d\t%.2f\t,c[i], b[i], a[i][0]);
for(int j=1;j<=n+n1;j++)
printf(%.2f\t, a[i][j]);
printf(\n);

}
printf(\n\t\t);
for(int i=0;i<=n+n1;i++)

printf(%.2f\t, f[i] );
printf(\n\t\t\t);
for(int i=1;i<=n+n1;i++)

printf(%.2f\t, a[0][i]-f[i]);
}
//verifica si face pasul
void verificIntrareIesire(float a[255][255], float c[255], float f[255], int b[255], int n, int n1, int &daca)
{
int intra=-1, iese, i, ;
float tempvar=0;
//verific daca Cj-fj <=0
for(i=1;i<=n+n1;i++)

if((a[0][i]-f[i])<=0)
tempvar++;


if(tempvar==n+n1)

{
daca=1;

afisez(\n\n\t\t\tS-a gasit optimul !);

}

else

{

//afla maximul din Cj-fj si retine pozitia de intrare
tempvar=0;
for(i=1;i<=n+n1;i++)
if((a[0][i]-f[i])>0 && tempvar<a[0][i]-f[i])
{
tempvar=a[0][i]-f[i];
intra=i;
}

//afla minimul dintre C(B)i si aij si retine pozitia de iesire
tempvar=999;
for(i=1;i<=n;i++)
if(a[i][intra]>0 && a[i][0]/a[i][intra]<tempvar)
{
tempvar=a[i][0]/a[i][intra];
iese=i;
}

8

if(iese>n+n1)
// daca nu exista nici un termen > 0 pe coloana de iesire ->
//programul se opreste fiindca nu are optim finit
{
daca=1;
afisez(\n\n\t\t\tNu exista optim finit !);
}
else
{
c[iese]=a[0][intra];

printf(\n\n\t\t\tIese a%d ; Intra a%d, b[iese], intra);
b[iese]=intra;

printf(\tPozitia pivotului %d %d, iese, intra);

afisez(\n\t\t\tApasati orice tasta pentru urmatorul pas...);
getch();
}

}
pas(a,n,n1,iese,intra);
}
int main ()
{
float matA[255][255], vectCb[255], vectF[255];
int nr_term, nr_termf, vectB[255], daca=0;
printf(Numarul de termeni in max f: ); scanf(%d, &nr_term);
printf(Numarul de ecuatii: ); scanf(%d, &nr_termf);
//se incarca datele
incarcDate(matA, vectCb, vectB,nr_term, nr_termf);

while(!daca)

{

produsScalar(matA, vectCb, vectF, nr_term, nr_termf);

afisezTabel(matA, vectCb, vectF, vectB, nr_term, nr_termf);

verificIntrareIesire(matA, vectCb, vectF,vectB,nr_term, nr_termf, daca);

}

afisez(\n\n\t\t\tCodat de Jerca Vlad gr. 152 sectia TI);

getch();
}

4. Executarea programului

Exemplul a.

10

Exemplul b.

11