Python linprog minimization–simplex method

Question:

I’m using scipy.optimize.linprog library to calculate the minimization using the simplex method. I’m working on this problem in my textbook and I’m hoping someone can point me in the right direction because I’m not getting the output I expect. The problem is:

Minimize          w = 10*y1 + 15*y2 + 25*y3
Subject to:       y1 + y2 + y3 >= 1000
                  y1 - 2*y2    >= 0
                            y3 >= 340
with              y1 >= 0, y2 >= 0

The code I wrote for this is:

import numpy as np
import pandas as pd
from scipy.optimize import linprog
A = np.array([
[1, 1, 1],
[1,-2, 0],
[0, 0, 1]])
b = np.array([1000,0,340])
c = np.array([-10,-15,-25])
res = linprog(c, A_ub=A, b_ub=b,
bounds=(0, None))
print('Optimal value:', res.fun, 'nX:', res.x)

Which gives the output:

Optimal value: -18400.0
X: [   0.  660.  340.]

I expect it to be:

Optimal value: -15100.0
X: [   660.  0.  340.]

I can’t seem to find consistency with this function but maybe it’s the way I’m using it.

Asked By: d84_n1nj4

||

Answers:

You’ve set up the inputs slightly wrong; see the manual. Specifically, you have a number of sign errors.

  1. Your vector c has the wrong sign; linprog minimizes c x so c should just be the coefficients in w = c x

  2. Your vector b and matrix A have the wrong sign. Their signs should be inverted to switch from your form of constraint f(x) >= const to the desired form for the linprog method, which is a less-than-or-equal, i.e. -f(x) <= - const

  3. You are missing the final two constraints.

  4. Your proposed minimum is < 0, which is obviously impossible as
    w = 10*x1 + 15*x2 + 25*x3 is always positive with your constraints as x1,x2,x3>=0.

The correct code reads:

import numpy as np
from scipy.optimize import linprog

A = np.array([[-1, -1, -1], [-1,2, 0], [0, 0, -1], [-1, 0, 0], [0, -1, 0]])
b = np.array([-1000, 0, -340, 0, 0])
c = np.array([10,15,25])

res = linprog(c, A_ub=A, b_ub=b,bounds=(0, None))

print('Optimal value:', res.fun, 'nX:', res.x)
# python2
# ('Optimal value:', 15100.0, 'nX:', array([ 660.,    0.,  340.]))
# python3
# Optimal value: 15099.999961403426 
# X: [6.59999996e+02 1.00009440e-07 3.40000000e+02]
Answered By: innisfree

As the positiveness of y1 and y2 can be guaranteed under bounds=(0, None), a simplified version of code is shown as below:

import numpy as np
from scipy.optimize import linprog

A = np.array([[-1, -1, -1], [-1,2, 0], [0, 0, -1]])
b = np.array([-1000, 0, -340])
c = np.array([10,15,25])

res = linprog(c, A_ub=A, b_ub=b,bounds=(0, None))
print('Optimal value:', res.fun, 'nX:', res.x) 

Output:

Optimal value: 15099.999961403195 

X: [6.59999996e+02 1.00009440e-07 3.40000000e+02]
Answered By: drobin
clc;
format longG
%inputan data
n=12;
c=21401;
K=349500;
p=6282.627;
h=823.529;
tau=1;
M=10000000;
x0=2852;
G=100000;
d=zeros(1,n);
d_=zeros(1,n);
z=zeros(1,n);
dtopi=zeros(1,n);
%data permintaan produk sandal per periode
d(1)=42148;
d(2)=23880;
d(3)=30400;
d(4)=26240;
d(5)=28992;
d(6)=23244;
d(7)=25000;
d(8)=28500;
d(9)=23212;
d(10)=31200;
d(11)=30400;
d(12)=28800;

dbar=mean2(d);
disp('dbar')
disp(dbar)
for k=1:n
dtopi(k)=abs(d(k)-dbar);
end
disp('maks dtopi')
disp(max(dtopi'))
for k=1:n
z(k)=(d(k)-dbar)/max(dtopi);
end
disp('z lama')
disp(z')
Z=sum(abs(z));
if(Z>=1)
for i=1:n
z(i)=1/n;
end
disp('z baru')
disp(z')
for k=1:n
d_(k)=d(k)-max(dtopi)*z(k);
end
end
disp('dk')
disp(d_')
for i=1:n
y_(i)=0;
end
for i=1:n
for j=1:i
y_(i) = y_(i)+d_(j);
end
disp('yi')
disp(y_(i))
end
%deviasi maksimum data sandal
d_g=max(dtopi);
%matriks
S1=ones(n);
S2=tril(S1); %matriks segitiga bawah
S3=eye(n); %matriks identitas
S4=zeros(n); %matriks zero
% matriks Ax=b
A=[h*S2 S4 -1*S3 h*tau*S3 h*S2;
-p*S2 S4 -1*S3 p*tau*S3 p*S2;
S4 S4 S4 -1*S3 -1*S3;
S3 -M*S3 S4 S4 S4;
S2 S4 S4 S3 S2];
disp('a')
disp(A)
b=[h*(-x0+y_(1)); h*(-x0+y_(2)); h*(-x0+y_(3)); h*(-x0+y_(4)); h*(-x0+y_(5)); h*(-x0+y_(6));
h*(-x0+y_(7)); h*(-x0+y_(8)); h*(-x0+y_(9)); h*(-x0+y_(10)); h*(-x0+y_(11)); h*(-x0+y_(12));
p*(x0-y_(1)); p*(x0-y_(2)); p*(x0-y_(3)); p*(x0-y_(4)); p*(x0-y_(5)); p*(x0-y_(6));
p*(x0-y_(7)); p*(x0-y_(8)); p*(x0-y_(9)); p*(x0-y_(10)); p*(x0-y_(11)); p*(x0-y_(12));
-d_g; -d_g; -d_g; -d_g; -d_g; -d_g; -d_g; -d_g; -d_g; -d_g; -d_g; -d_g;
0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0;
G-x0+y_(1); G-x0+y_(2); G-x0+y_(3); G-x0+y_(4); G-x0+y_(5); G-x0+y_(6)
G-x0+y_(7); G-x0+y_(8); G-x0+y_(9); G-x0+y_(10); G-x0+y_(11); G-x0+y_(12)];
disp('b')
disp(b)
D=[c; c; c; c; c; c; c; c; c; c; c; c;
K; K; K; K; K; K; K; K; K; K; K; K;
1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1;
0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0];
disp('D')
disp(D)
LB=[0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0;
1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1;
0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0];
disp('LB')
disp(LB)
UB=[25000; 25000; 25000; 25000; 25000; 25000;
25000; 25000; 25000; 25000; 25000; 25000;
1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1;
inf; inf; inf; inf; inf; inf; inf; inf; inf; inf; inf; inf;
25000; 25000; 25000; 25000; 25000; 25000;
25000; 25000; 25000; 25000; 25000; 25000;
inf; inf; inf; inf; inf; inf; inf; inf; inf;
inf; inf; inf];
disp('UB')
disp(UB)
x=linprog(D,A,b,[],[],LB,UB);

anyone can help me to convert this matlab code to the python? I stuck in linprog and get error

Answered By: Epul Saepulloh