I am using cplex for an optimization model, to optimize diet compositions. Now I would like to add an extra variable/KPI, which is the sum of other KPIs in the model. However, this sum is a score with maximum values, which means that when each KPI exceeds a certain upper limit, the sum should not consider values above this value. The score is just a measure for each food composition, and therefore, the upper limits are not contraints to the model, but just limits to calculate the scores, so it should not affect the model results. Finally, I would like to minimize the total score.
I have tried to add this using mdl.sum to sum each indicator and added them to a list, and then I have tried to replace the sum by values of another list if the upper limits were exceeded. See example below:
# Decision variables, limited to be >= Food.qmin and <= Food.qmax
ftype = mdl.integer_vartype if ints else mdl.continuous_vartype
qty = mdl.var_dict(foods, ftype, lb=lambda f: f.qmin,ub=lambda f: f.qmax, name=lambda f:
"q_%s" % f.name)
# Limit range of nutrients, and mark them as KPIs
for c in constraints:
amount = mdl.sum(qty[f] * food_constraints[f.name, c.name] for f in foods)
mdl.add_range(c.qmin, amount, c.qmax)
mdl.add_kpi(amount, publish_name="Total %s" % c.name)
# add sum of indicators with max values:
score1 = mdl.sum(qty[f] * f.veg for f in foods)
score2 = mdl.sum(qty[f] * f.fruit for f in foods)
score3 = mdl.sum(qty[f] * f.fish for f in foods)
# add sum of indicators without max values:
score4 = mdl.sum(qty[f] * f.sugar for f in foods)
score5 = mdl.sum(qty[f] * f.fats for f in foods)
Score_sum_A = [score1, score2, score3]
max_scores = [10.6, 3.3, 9.7]
# cap values of Score_sum_A to max scores:
for i in range(len(max_scores)):
if Score_sum_A[i] >= max_scores[i]:
Score_sum_A[i] = max_scores[i]
else:
Score_sum_A[i] = Score_sum_A[i]
Score_sum_B = [score4, score5]
total_score_sum = sum(Score_sum_A + Score_sum_B)
mdl.add_kpi(total_score_sum , 'Total food score')
mdl.minimize(total_score_sum)
However, when running the model, I get the error: "TypeError: Cannot convert linear constraint to a boolean value", which is because of the if statement. So it seems like the model cannot operate with this sort of if statement inside the model.
Does anyone know, whether it is possible in cplex to add such a indicator with maximum values, without contraining the model results?
Any hint would be highly appreciated.
Thanks!
You cannot write
since Score_sum_A is not a constant. You should use max
or if_then from docplex
If I change slighly https://ibmdecisionoptimization.github.io/docplex-doc/mp/diet.html
from
to
then I will get
In a smaller example like zookpi
adding
will give