# simplex algorithm for optimization (LP)
def simplex(f,contraints):
(matrix,ans) = create_tableau(f,contraints)
while True:
#print "TAB: \n",matrix,ans,"\n\n\n"
pivot_column = select_pivot_column(matrix)
if pivot_column == -1:
result = calculate_answer(matrix,ans)
break
pivot_row = select_pivot_row(matrix,ans,pivot_column)
#print "PIVOT: ",pivot_column,pivot_row,"\n\n\n"
(matrix,ans) = pivoting(matrix,ans,pivot_row,pivot_column)
return result
def create_tableau(f,constraints):
matrix = list()
ans = list()
n_dim = len(f)
n_const = len(constraints)
for i in range(len(constraints)):
(c,a) = constraints[i]
matrix.append(c)
matrix[i].extend([0.0 for x in range(n_const+1)])
matrix[i][n_dim+i]=1.0
ans.append(a)
matrix.append(f)
matrix[n_const].extend([0.0 for x in range(n_const+1)])
matrix[n_const][n_dim+n_const]=1.0
ans.append(0.0)
return (matrix,ans)
def calculate_answer(matrix,ans):
answer=list()
for i in range(len(matrix[0])):
active = False
val_active = 0
for j in range(len(ans)):
if matrix[j][i]!=0:
if not active:
active=True
val_active = ans[j]/matrix[j][i]
else:
val_active=0
break
answer.append(val_active)
return answer
def pivoting(matrix,ans,i,j):
piv_val = matrix[i][j]
for k in range(len(matrix[i])):
matrix[i][k]=matrix[i][k]/piv_val
ans[i]=ans[i]/piv_val
for l in range(len(matrix)):
if l==i:
continue
new_row = list()
for k in range(len(matrix[-1])):
new_row.append(matrix[i][j]*matrix[l][k]-matrix[l][j]*matrix[i][k])
ans[l]=matrix[i][j]*ans[l]-matrix[l][j]*ans[i]
matrix[l]=new_row
return (matrix,ans)
def select_pivot_column(matrix):
min_val = min(matrix[-1])
min_i = matrix[-1].index(min_val)
if min_val<0.0:
return min_i
else:
return -1
def select_pivot_row(matrix,ans,pivot_column):
pivot_row = -1
for i in range(len(matrix)-1):
if matrix[i][pivot_column]>0:
val = ans[i]/matrix[i][pivot_column]
if pivot_row==-1 or val<max_val:
max_val = val
pivot_row = i
return pivot_row
print simplex([-52.4,-73.0,-83.4, -41.8],
[([1.5,1.0,2.4,1.0],200.0),
([1.0,5.0,1.0,3.5],800.0),
([1.5,3.0,3.5,1.0],500.0)])