Source code for Simplex
import numpy as np
[docs]class Simplex:
"""
This class creates a simplex solver for linear programming.
"""
def __init__(self,c = None,A = None ,b = None, problem = None, verbose = None):
"""
Creates variables associated to the linear programing problem
:type c: numpy 1D array
:param c: array asociated with the cost or coefficients of
lineal objective function.
:type A: numpy NxM array
:param A: Matrix associated to the linear restrictions for
the objective function.
:type b: numpy 1XM array
:param b: array asociated with constraints to the linear
restrictions for the objective function.
:type problem: str
:param problem: definition of maximization ('Max') or
minimization ('Min') problem.
:type x: numpy 1D array
:param x: array of solution vector once the
solve method is applied.
"""
if problem == 'Max':
self.c=-np.array(c)
else:
self.c= np.array(c)
self.A=np.array(A)
self.b=np.array(b)
self.x = np.zeros(self.b.size)
self.problem = problem
self.verbose = verbose
[docs] def solve(self):
"""
Solves the simplex algorithm.
Returns
-------
:solution: Numpy array with solution
"""
problem = self.problem
verbose = self.verbose
c_N = self.c
A = self.A
b = self.b
status = []
costo = np.copy(c_N)
n_c_N = c_N.size
n_A = np.size(A,0)
identity_A = np.eye(n_A)
B = np.eye(n_A)
A= np.hstack((A,identity_A))
n_b = b.size
x_B = b
c_B = np.zeros(n_b)
n_A_ = np.size(A,1)
N_list_idx = list(range(0,n_c_N))
B_list_idx = list(range(n_c_N,n_A_))
nu = np.zeros(n_b)
lista = []
i = 0
for lambda_ in c_N:
lista.append (-lambda_ + nu@A[:, N_list_idx[i]]) ##Adding blas optimization
i = i + 1
idx_x_N = lista.index(max(lista))
while lista[idx_x_N]>0:
d = np.linalg.solve(B, A[:,idx_x_N])
lista2 = []
for indice in range(0,n_b):
if d[indice]<=0:
lista2.append(np.nan)
else:
lista2.append(x_B[indice]/d[indice])
if np.isnan(lista2).all() == True:
status = 3
return ("simplex method failed, unbounded solution",-1, status)
idx_x_B = lista2.index(min(np.array(lista2)[np.isfinite(lista2)]))
x_min_plus = x_B[idx_x_B]/d[idx_x_B]
x_B = x_B - d*x_min_plus
x_B[idx_x_B] = x_min_plus
B[:,idx_x_B] = A[:,idx_x_N]
aux = B_list_idx[idx_x_B]
B_list_idx[idx_x_B] = N_list_idx[idx_x_N]
N_list_idx[idx_x_N] = aux
aux = c_B[idx_x_B]
c_B[idx_x_B] = c_N[idx_x_N]
c_N[idx_x_N] = aux
nu = np.linalg.solve(B.T, c_B)
lista = []
i = 0
for lambda_ in c_N:
lista.append (-lambda_ + nu@A[:, N_list_idx[i]]) ###adding blas optimization
i = i + 1
idx_x_N = lista.index(max(lista))
solution = []
for indice in range(0,n_c_N):
j=0
for indice2 in range(0,len(B_list_idx)):
if B_list_idx[indice2] == indice:
solution.append(x_B[indice2])
j = j + 1
elif (indice2 == len(B_list_idx) - 1 and j == 0):
solution.append(0)
if verbose == True:
print("Optimization completed successfully !")
print("Solution for x vector:")
self.x = solution
print(solution)
status = 0
n = len(solution)
opt = 0
for i in range(n):
opt += solution[i]* costo[i] ###Blas optimization
if verbose == True:
print("Optimal value:")
print(opt)
print("Solution for x vector, optimization value and status:")
#Solucion
self.x = solution
return solution, opt, status