I am building an multi-objective optimization model with a quadratic constraint. However, when I solve the model I get the following error :
CPLEX Error 1031: Not available for QCP
When I replace multi-objective function with the single objective objective function, I get the following error :
CPLEX Error 5002: 'q1' is not convex.
I am enclosing the code. There is one quadratic constraint that gets introduced as I need to calculate the average margin (total margin / number of items). Now, both numerator and denominator expression have decision variables, I have used logical constraints (using indicator variables to get my way through). Is there any other way of calculating average, without making the constraint quadratic ?
mdl = Model('assortment_optimization')
sku_binary_var = mdl.binary_var_dict(skus, lb = 0, ub = 1, name = lambda p: '%s' % p)
num_sku_selected = mdl.integer_var(name = 'total_selected_sku')
mdl.add_constraint(num_sku_selected == mdl.sum(sku_binary_var[i] for i in skus))
mdl.add_constraint(mdl.sum(sku_binary_var[i] * sku_char[i]['shelf_capacity'] * sku_char[i]['item_cbm'] for i in skus) <= VOLUME_CAPACITY_CBM, ctname = 'volume_constraint')
mdl.add_constraint(mdl.sum(sku_binary_var[i] * sku_char[i]['shelf_capacity'] * sku_char[i]['cost'] for i in skus) <= MAX_COST, ctname = 'cost_constraint')
# mdl.add_constraint(mdl.sum(sku_binary_var[i] for i in skus) <= 233)
tot_margin = mdl.continuous_var(name = 'tot_margin')
avg_margin = mdl.continuous_var(name = 'avg_margin')
mdl.add_constraint(tot_margin == mdl.sum(sku_binary_var[i] * sku_char[i]['avg_wk_sales_units'] * sku_char[i]['margin'] for i in skus))
# indicator constraints to help calculate average margin
indic_varbs = mdl.binary_var_dict(range(1, len(skus)+1))
for i in range(1, len(skus)+1):
mdl.add_indicator(indic_varbs[i], num_sku_selected == i, active_value = 1)
mdl.add_constraint(mdl.sum(indic_varbs[i] for i in range(1, len(skus)+1)) == 1)
# this becomes a quadratic constraint
mdl.add_constraint(avg_margin == tot_margin * mdl.sum(indic_varbs[i] * (1 / i) for i in range(1, len(skus) + 1)))
mdl.add_constraint(avg_margin >= 8)
mdl.add_kpi(num_sku_selected, 'Number of SKUs in the new assortment')
# below are the objectives that I'd like to maximize
obj_margin = mdl.sum(sku_binary_var[i] * sku_char[i]['avg_wk_sales_units'] * sku_char[i]['margin'] for i in skus)
obj_freq = mdl.sum(sku_binary_var[i] * sku_char[i]['freq_trans'] for i in skus)
obj_unique = mdl.sum(sku_binary_var[i] * sku_char[i]['uniq_factor'] for i in skus)
# mdl.maximize(obj_margin)
mdl.maximize_static_lex(exprs=[obj_margin, obj_freq, obj_unique])
mdl.solve(log_output=True)
------------------------------
Bhartendu Awasthi
------------------------------
#DecisionOptimization