from scipy.optimize import linprog
import numpy as np
# Define the problem:
# The lpLib library is a LP-library that can easily load UB, LB and EQ constraints
import lpLib as LP

# x_1 to x_6 are order size for each month (October = 1, November = 2, etc).
# x_7 to x_12 are inventory level at end of month (October = 7, November = 8, etc)
#
# y_1 to y_6 are binary variables, 1 = Order, 0 = Do not order

months = ["Oct","Nov","Dec","Jan","Feb","Mar"]
c = [100, 100, 110, 120, 100, 100, 5, 5, 5, 5, 5, 5]
nVar = len(c)
d = [40, 20, 30, 40, 30, 20] # Demand
maxOrder = [50,50, 50, 50, 50, 50]
y = [1,1, 1, 1, 1, 1] 
nMonths = len(d)
c_F = 200

#
# The following constraints ensures that we do not order more than 50 units, if we order:
#
# 1 * x_i <= 50 * y_i, i = 1,...,6
#
#
#
# In principle, we should test all combinations of y_i, but if we
# assume that only for one month we have y_i = 0, we just systematically
# check monty by month, if there is one month not to order...
# 
#
best=1e30

print("Testing for each month not to order")
for j in range(nMonths):
   y[j] = 0  # This means to run the model as in Problem 2.5, but without order in month j
   LP.coefficients(c,True)
   for i in range(nMonths):
       A_i = np.zeros([nVar])
       A_i[i] = 1
       LP.upperBound(maxOrder[i]*y[i],A_i) 
   for i in range(nMonths):
       A_i = np.zeros([nVar])
       A_i[i] = 1
       A_i[i+nMonths] = -1
       if i > 0:
           A_i[i+nMonths-1] = 1        
       LP.equalityConstraint(d[i],A_i)
   for i in range(nMonths):
       A_i = np.zeros([nVar])
       A_i[i + nMonths]= 1
       LP.upperBound(30,A_i)   
   res=LP.lpSolve(True)
   y[j] = 1 # Reset value when done...
   if res.status == 0: # No error, if error, we cannot skip order this month 
       test = res.fun + 5*c_F      
       print("Month =",months[j],"without order, Cost = ",res.fun + 5*c_F)
       if test < best:
          best = test
          x = res.x
          best_j = j
print("Minimu cost for y_" + str(j+1) ,"= 0")
print("Minimum cost = ", best)
for i in range(nMonths):
      print(months[i]+", x_" + str(i+1),"=",x[i])
