Good morning,
I am trying to solve a non-linear optimization problem by using the package cyipopt in python. I think my problem is related to the way I am defining my constraints, but being my code the following:
#Define the parameters
nr_sku = df_sku_demand_stockout.shape[0]
s = df_sku_demand_stockout['demand_rate'].astype('float').tolist()
s_est = [0] * nr_sku #demand_rate estimated
intrinsic_demand = [0] * nr_sku
#si = si.to_numpy()
sigma = df_sku_demand_stockout['prob_stockout'].astype('float').tolist()
#sigmai = sigmai.to_numpy()
i = 0
j = 0
sub_rate = [[0 for i in range(nr_sku)] for j in range(nr_sku)]
#Define the objective function
def objective_function(x, s, sigma):
intrinsic_demand = x[:nr_sku]
sub_rate = x[nr_sku:].reshape((nr_sku, nr_sku))
s_est = [0] * nr_sku
for i in range(nr_sku):
for j in range(nr_sku):
if i == j:
s_est[i] = intrinsic_demand[i]
else:
s_est[i] += sub_rate[j][i] * intrinsic_demand[j] * sigma[j]
e = sum((s[i] - s_est[i])**2 for i in range(nr_sku))
return e
from scipy.optimize import minimize
from scipy.optimize import LinearConstraint
from scipy.optimize import Bounds
# Define the constraints
def constraint_fun_1(x):
sub_rate = x[nr_sku:].reshape((nr_sku, nr_sku))
return sub_rate.sum(axis=1) - 1
# Define the bounds
#bounds = Bounds([0] * nr_sku + [0] * nr_sku**2, [1] * nr_sku + [1000] * nr_sku**2)
#lb = bounds.lb
#ub = bounds.ub
intrinsic_demand_bounds = ([0] * nr_sku, [1] * nr_sku)
sub_rate_bounds = ([0] * nr_sku**2, [np.inf] * nr_sku**2)
concat_bounds = (intrinsic_demand_bounds,sub_rate_bounds)
cons = [
{'type': 'eq', 'fun': lambda x: constraint_fun_1}]
# Define the initial guess
x0 = [0] * (nr_sku + nr_sku**2)
# Run optimization
res = minimize_ipopt(
objective_function,
x0,
bounds= concat_bounds,
constraints=cons,
jac=lambda x: grad(lambda x: objective_function(x))(x),
options={
'mu_strategy': 'adaptive',
'max_iter': 1000,
'tol': 1e-6,
'print_level': 5
}
)
# Extract results
intrinsic_demand_opt = res.x[:nr_sku]
sub_rate_opt = res.x[nr_sku:].reshape((nr_sku, nr_sku))
I get the following error message: ValueError: lb and ub must either be None or have length n.
If someone could help :D! Thanks in advance!
I tried changing the constraint to a boolean, but it seems that this package doesn't support a boolean as a constraint - the idea is that the sum of each row in sub_rate[i][j] = 1.