PES Pesquisa Operacional

Prof. Milton Procópio de Borba

Originais do Prof. Fernando Deeke Sasse

 

4. Programação Linear: Soluções Factíveis e Soluções Básicas Factíveis

4.1 Exemplo 1

Este exemplo ilustra o fato estabelecido pelo teorema que afirma que, se um sistema linear com m <= n admite uma solução factível, ele também admite uma solução básica factível.

Consideremos o seguinte conjunto de restrições:

3*x[1]+5*x[3]-6*x[4] <= 4 ,

2*x[1]-6*x[2]+x[3]+5*x[4] = 1 ,

x[1]/2+x[2]+5*x[3] = 10 ,

0 < x[1] , 0 < x[2] , 0 < x[3] , 0 < x[4] .

Solução : Para transformar a desigualdade em equação devemos introduzir a variável de folga x[5] . Temos então

3*x[1]+5*x[3]-6*x[4]+x[5] = 4 ,

2*x[1]-6*x[2]+x[3]+5*x[4] = 1 ,

x[1]/2+x[2]+5*x[3] = 10 ,

0 < x[1] , 0 < x[2] , 0 < x[3] , 0 < x[4] , 0 < x[5] , 0 < x[6] , 0 < x[7] .

Vamos inicialmente gerar a matriz do sistema:

> restart:

> with(linalg):

Warning, the protected names norm and trace have been redefined and unprotected

> sistema:=[3*x[1]-0*x[2]+5*x[3]-6*x[4]+x[5] = 4,2*x[1]-6*x[2]+x[3]+5*x[4] = 1,1/2*x[1]+x[2]+5*x[3]+0*x[4]= 10];

sistema := [3*x[1]+5*x[3]-6*x[4]+x[5] = 4, 2*x[1]-6...

> A:=genmatrix(sistema,[x[1],x[2],x[3],x[4],x[5]],RHS);

A := matrix([[3, 0, 5, -6, 1], [2, -6, 1, 5, 0], [1...

> evalm(A);

matrix([[3, 0, 5, -6, 1], [2, -6, 1, 5, 0], [1/2, 1...

> b:=evalm(RHS);

b := vector([4, 1, 10])

>

Vamos associar um vetor a[j] a cada coluna de A :

> for j to 5 do a[j]:=col(A,j) od;

a[1] := vector([3, 2, 1/2])

a[2] := vector([0, -6, 1])

a[3] := vector([5, 1, 5])

a[4] := vector([-6, 5, 0])

a[5] := vector([1, 0, 0])

Devemos escolher uma matriz base B e obter a primeira solução factível básica. Se escolhermos aleatóriamente as colunas a serem eliminadas podemos obter soluções básicas não-factíveis. Por exemplo,

> B:=augment(a[1],a[2],a[3]);

B := matrix([[3, 0, 5], [2, -6, 1], [1/2, 1, 5]])

A solução básica é :

> xB:=evalm(B^(-1)&*b);

xB := vector([-181/68, -89/136, 163/68])

que é não-factível, pois nem todas as componentes de xB são não-negativas.

Devemos então usar algum critério que nos permita determinar qual coluna deve ser zerada.

Uma solução factível é

> x[4]:=2;x[5]:=1/2;

x[4] := 2

x[5] := 1/2

> sistema;

[3*x[1]+5*x[3]-23/2 = 4, 2*x[1]-6*x[2]+x[3]+10 = 1,...

> op(sistema);

3*x[1]+5*x[3]-23/2 = 4, 2*x[1]-6*x[2]+x[3]+10 = 1, ...

> ss:=solve({op(sistema)},{x[1],x[2],x[3]});

ss := {x[2] = 759/272, x[3] = 151/136, x[1] = 451/1...

>

> assign(ss);

> x[2];

759/272

Determinemos os coeficientes alpha[i] que fazem a combinação linear das colunas a[i] .

> zer:=vector(5,[0,0,0,0,0]);

zer := vector([0, 0, 0, 0, 0])

> eq1:=evalm(add(alpha[i]*a[i],i=1..5));

eq1 := vector([3*alpha[1]+5*alpha[3]-6*alpha[4]+alp...

> set_eqs:={seq(eq1[i]=0,i=1..3)};

set_eqs := {3*alpha[1]+5*alpha[3]-6*alpha[4]+alpha[...

> vars:={seq(alpha[j],j=1..5)};

vars := {alpha[2], alpha[4], alpha[1], alpha[5], al...

> sol:=solve(set_eqs,vars);

sol := {alpha[1] = -2*alpha[2]-10*alpha[3], alpha[5...

> assign(sol);

> alpha[2]:=1;alpha[3]:=1;

alpha[2] := 1

alpha[3] := 1

> seq(alpha[k],k=1..5);

-12, 1, 1, 29/5, 329/5

A coluna a ser retirada terá índice dado por x[r]/y[r] = min[j] x[j]/alpha[j] , 0 < alpha[j]

Ou seja,

> S:=evalf([x[2]/alpha[2],x[3]/alpha[3],x[4]/alpha[4],x[5]/alpha[5]]);

S := [2.790441176, 1.110294118, .3448275862, .75987...

Portanto, será eliminada a coluna a[5] . O novo sistema será

> restart:

> with(linalg):

Warning, the protected names norm and trace have been redefined and unprotected

> A := matrix([[3, 0, 5, -6], [2, -6, 1, 5], [1/2, 1, 5, 0]]);

A := matrix([[3, 0, 5, -6], [2, -6, 1, 5], [1/2, 1,...

> b := vector([4, 1, 10]);

b := vector([4, 1, 10])

Vamos associar um vetor a[j] a cada coluna de A :

> for j to 4 do a[j]:=col(A,j) od;

a[1] := vector([3, 2, 1/2])

a[2] := vector([0, -6, 1])

a[3] := vector([5, 1, 5])

a[4] := vector([-6, 5, 0])

>

> X:=vector(4,[x1,x2,x3,x4]);

X := vector([x1, x2, x3, x4])

> eq1:=evalm(A&*X-b);

eq1 := vector([3*x1+5*x3-6*x4-4, 2*x1-6*x2+x3+5*x4-...

> eq1[1];

3*x1+5*x3-6*x4-4

> eqs:={seq(eq1[j]=0,j=1..3)};

eqs := {3*x1+5*x3-6*x4-4 = 0, 2*x1-6*x2+x3+5*x4-1 =...

> sol1:=solve(eqs,{x1,x2,x3,x4});

sol1 := {x4 = x4, x1 = -181/68+211/68*x4, x2 = -89/...

>

> assign(sol1);

Escolhendo

> x4:=1;

x4 := 1

obtemos uma solução factível:

> seq(X[j],j=1..3);

15/34, 75/68, 59/34

Determinemos os coeficientes alpha[i] que fazem a combinação linear das colunas a[i] .

>

> zer4:=vector(4,[0,0,0,0]);

zer4 := vector([0, 0, 0, 0])

> eq1:=evalm(add(alpha[i]*a[i],i=1..4));

eq1 := vector([3*alpha[1]+5*alpha[3]-6*alpha[4], 2*...

> set_eqs:={seq(eq1[i]=0,i=1..3)};

set_eqs := {3*alpha[1]+5*alpha[3]-6*alpha[4] = 0, 2...

> vars:={seq(alpha[j],j=1..4)};

vars := {alpha[1], alpha[2], alpha[3], alpha[4]}

> sol:=solve(set_eqs,vars);

sol := {alpha[4] = -68/45*alpha[3], alpha[2] = -239...

> assign(sol);

> alpha[3]:=1;

alpha[3] := 1

> seq(alpha[k],k=1..4);

-211/45, -239/90, 1, -68/45

A coluna a ser retirada terá índice dado por x[r]/y[r] = min[j] x[j]/alpha[j] , 0 < alpha[j]

Ou seja,

Portanto, eliminamos a coluna a[3] e chegamos a uma matriz básica (3x3):

> restart:

> with(linalg):

> A := matrix([[3, 0, -6], [2, -6, 5], [1/2, 1, 0]]);

A := matrix([[3, 0, -6], [2, -6, 5], [1/2, 1, 0]])

> b := vector([4, 1, 10]);

b := vector([4, 1, 10])

A solução básica é :

> xB:=evalm(A^(-1)&*b);

xB := vector([386/45, 257/45, 163/45])

que é factível, por construção.

4.2 Exemplo 2

Seja o sistema A*X = b onde

> restart:

> with(linalg):

Warning, the protected names norm and trace have been redefined and unprotected

> A := matrix([[2, 0, 1, -6, 1, 11], [6, 2, 1, 7, 0, 3], [1, 2, 5, 0, 5, 1],[2,4,-2,3,0,1]]);

A := matrix([[2, 0, 1, -6, 1, 11], [6, 2, 1, 7, 0, ...

> b:=matrix([[45], [32], [34], [11]]);

b := matrix([[45], [32], [34], [11]])

Podemos verificar que uma solução factível para este problema é dada por

> X:= vector(6,[1, 2, 3, 1, 2, 4]);

X := vector([1, 2, 3, 1, 2, 4])

> evalm(A&*X);

vector([45, 32, 34, 11])

Note que que podemos uma solução básica factível por tentativa e erro.

> for j to 6 do a[j]:=col(A,j) od;

a[1] := vector([2, 6, 1, 2])

a[2] := vector([0, 2, 2, 4])

a[3] := vector([1, 1, 5, -2])

a[4] := vector([-6, 7, 0, 3])

a[5] := vector([1, 0, 5, 0])

a[6] := vector([11, 3, 1, 1])

Eliminando as linhas 4 e 5 temos

> B:=augment(a[4],a[2],a[3],a[6]);

B := matrix([[-6, 0, 1, 11], [7, 2, 1, 3], [0, 2, 5...

> linsolve(B,b);

matrix([[1100/947], [5957/1894], [4434/947], [4071/...

o que mostra que a solução básica é factível.

Utilize o critério empregado no exemplo anterior para determinar uma solução básica factível.

> evalm(a[1]);

vector([2, 6, 1, 2])

>

> for j to 6 do a[j]:=col(A,j) od;

a[1] := vector([2, 6, 1, 2])

a[2] := vector([0, 2, 2, 4])

a[3] := vector([1, 1, 5, -2])

a[4] := vector([-6, 7, 0, 3])

a[5] := vector([1, 0, 5, 0])

a[6] := vector([11, 3, 1, 1])

> zer:=vector(6,[0,0,0,0,0,0]);

zer := vector([0, 0, 0, 0, 0, 0])

> eq1:=evalm(add(alpha[i]*a[i],i=1..6));

eq1 := vector([2*alpha[1]+alpha[3]-6*alpha[4]+alpha...

> set_eqs:={seq(eq1[i]=0,i=1..4)};

set_eqs := {2*alpha[1]+alpha[3]-6*alpha[4]+alpha[5]...
set_eqs := {2*alpha[1]+alpha[3]-6*alpha[4]+alpha[5]...

> vars:={seq(alpha[j],j=1..6)};

vars := {alpha[1], alpha[2], alpha[3], alpha[4], al...

> sol:=solve(set_eqs,vars);

sol := {alpha[4] = -1198/87*alpha[2]-231/29*alpha[5...

> assign(sol);

> alpha[2]:=1;alpha[5]:=1;

alpha[2] := 1

alpha[5] := 1

> seq(alpha[k],k=1..6);

3022/87, 1, -416/87, -1891/87, 1, -517/29

> S:=evalf([X[1]/alpha[1],X[2]/alpha[2],X[5]/alpha[5]]);

S := [.2878888154e-1, 2., 2.]

Portanto devemos eliminar a coluna a[1]

> restart:

> with(linalg):

Warning, the protected names norm and trace have been redefined and unprotected

> A := matrix([[ 0, 1, -6, 1, 11], [ 2, 1, 7, 0, 3], [ 2, 5, 0, 5, 1],[4,-2,3,0,1]]);

A := matrix([[0, 1, -6, 1, 11], [2, 1, 7, 0, 3], [2...

> b:=matrix([[45], [32], [34], [11]]);

b := matrix([[45], [32], [34], [11]])

> X:=vector(5,[x1,x2,x3,x4,x5]);

X := vector([x1, x2, x3, x4, x5])

> eq1:=evalm(A&*X-b);

eq1 := matrix([[x2-6*x3+x4+11*x5-45], [2*x1+x2+7*x3...

> eq1[3,1];

2*x1+5*x2+5*x4+x5-34

> eqs:=[seq(eq1[j,1]=0,j=1..4)];

eqs := [x2-6*x3+x4+11*x5-45 = 0, 2*x1+x2+7*x3+3*x5-...

> sol1:=solve({op(eqs)},{x1,x2,x3,x5});

sol1 := {x1 = 5957/1894-564/947*x4, x3 = 1100/947+2...

>

> assign(sol1);

Escolhendo

> x4:=1;

x4 := 1

obtemos uma solução factível:

> seq(X[j],j=1..5);

4829/1894, 3692/947, 1323/947, 1, 4174/947

>

> for j to 5 do a[j]:=col(A,j) od;

a[1] := vector([0, 2, 2, 4])

a[2] := vector([1, 1, 5, -2])

a[3] := vector([-6, 7, 0, 3])

a[4] := vector([1, 0, 5, 0])

a[5] := vector([11, 3, 1, 1])

> zer:=vector(5,[0,0,0,0,0]);

zer := vector([0, 0, 0, 0, 0])

> eq1:=evalm(add(alpha[i]*a[i],i=1..5));

eq1 := vector([alpha[2]-6*alpha[3]+alpha[4]+11*alph...

> set_eqs:={seq(eq1[i]=0,i=1..4)};

set_eqs := {alpha[2]-6*alpha[3]+alpha[4]+11*alpha[5...

> vars:={seq(alpha[j],j=1..5)};

vars := {alpha[1], alpha[2], alpha[3], alpha[4], al...

> sol:=solve(set_eqs,vars);

sol := {alpha[4] = -947/564*alpha[1], alpha[3] = -2...

> assign(sol);

> alpha[1]:=1;

alpha[1] := 1

> seq(alpha[k],k=1..5);

1, 371/282, -223/564, -947/564, -103/564

> S:=evalf([X[1]/alpha[1],X[2]/alpha[2]]);

S := [2.549630412, 2.963377043]

Eliminamos a coluna a1:

> restart:

> with(linalg):

Warning, the protected names norm and trace have been redefined and unprotected

> A := matrix([[ 1, -6, 1, 11], [ 1, 7, 0, 3], [ 5, 0, 5, 1],[-2,3,0,1]]);

A := matrix([[1, -6, 1, 11], [1, 7, 0, 3], [5, 0, 5...

> b:=matrix([[45], [32], [34], [11]]);

b := matrix([[45], [32], [34], [11]])

Por contrução, tal solução básica deve ser factível. De fato,

> linsolve(A,b);

matrix([[307/564], [2713/1128], [5957/1128], [5497/...

>

4.3 Exercício

Defina um sistema Ax = b, com 3 equações e 5 incógnitas, de modo que ele admita uma solução factível. Determine então ao menos uma solução básica factível usando (i) tentativa e erro e (ii) a redução mostrada nos exemplos anteriores. A solução poderia ser iniciada da seguinte forma:

> restart;

> with(linalg):

Warning, the protected names norm and trace have been redefined and unprotected

> m:=3;n:=5;

m := 3

n := 5

> A:=randmatrix(m,n,entries=rand(0..150));

A := matrix([[147, 88, 128, 101, 64], [32, 89, 27, ...

> b:=randvector(m,entries=rand(0..100));

b := vector([39, 11, 14])

> x:=vector(n);

x := array(1 .. 5,[])

> LHS:=multiply(A,x);

LHS := vector([147*x[1]+88*x[2]+128*x[3]+101*x[4]+6...

> sistema:={seq(LHS[i]=b[i],i=1..m)};

sistema := {147*x[1]+88*x[2]+128*x[3]+101*x[4]+64*x...
sistema := {147*x[1]+88*x[2]+128*x[3]+101*x[4]+64*x...

>