Accessing objective terms
AnsweredDear all,
I am using a Python function which returns 'm', a gurobi.Model object. In a next step, I call m.optimize(). Afterwards, I can use m.objval, m.getVars(), etc. to access my results. However, the objective function of my model consists of multiple parts. This means:
obj_1 = LinExpr(...), obj_2 = LinExpr(...), ..., obj_x = LinExpr(...)
My model then optimizes for a normalized and weighted combined objective:
combined_obj = obj_1 + obj_2 + obj_3
How can I access the individual objective terms? Unfortunately, I cannot call m.obj_1.getValue() or something similar.
Thanks for answering my question!
Best wishes,
Jonas
-
Hi Jonas,
I think you can use the Multiple Objectives feature of Gurobi.
With Model.setObjectiveN() (for example for python) you can add your different objectives. By setting the same priority for all objectives you have the blending approach that creates a single objective by taking a linear combination of your objectives. How to query the objective results can be seen in the example given here.I hope this helps,
Marika0 -
Dear Marika,
thanks for your quick reply!
I already read about your multiple objectives feature. However, as my individual objective terms are normalized, I would have to re-calculate the 'real-sized' objective values when using it.
Is there any convenient way to circumvent this? Thanks!
Best wishes,
Jonas0 -
Hi Jonas,
I do not know whether I understand you correctly. If you add the individual objectives with setObjectiveN() you can give the weight to be used for the blended multi-objective optimization. When querying for the individual objectives this weight is not considered.
Or what exactly do you mean by "individual objective terms are normalized"?
Best regards,
Marika0 -
Hi Marika,
the objective function is of the following form:
The sigmas represent the individual objective weights, whereas LB and UB are lower and upper bounds respectively. How can I know access the 'z_1' value for example? Thanks!
Best wishes,
Jonas0 -
And another follow-up question: I read that there is no direct way to access shadow prices (constr.Pi) using the Gurobi multi-objective optimization. Do you know any way how to circumvent this issue? Thanks!
0 -
Hi Jonas,
You can access the solution value of a variable using the attribute X.
Yes, the attribute Pi is not available when using the multi-objective feature.
If you need the shadow prices and since you have blended objectives, I would probably define variables for each objective and define the total objective without the feature like for example:import gurobipy as gp
from gurobipy import GRB
model = gp.Model("MultiObjModel")
z1 = model.addVar(lb=0.3, ub=5, vtype=GRB.CONTINUOUS, name="z1")
z2 = model.addVar(lb=2, ub=10, vtype=GRB.CONTINUOUS, name="z2")
obj1 = model.addVar(vtype=GRB.CONTINUOUS, name="obj1")
obj2 = model.addVar(vtype=GRB.CONTINUOUS, name="obj2")
model.update()
# constraint of the model
constr = model.addConstr(z1 +z2 >= 4, name="Constr1")
# define individual objectives (and assign to variable)
model.addConstr(obj1 == ((z1 - z1.lb) / (z1.ub - z1.lb)))
model.addConstr(obj2 == (z2 - z2.lb) / (z2.ub - z2.lb))
# combine the individual objectives
model.setObjective(2 * obj1 + obj2)
model.optimize()
#output of shadow price
print(constr.Pi)
# ouptut some solution values
if model.SolCount > 0:
print(z1.X)
print(obj1.X)In this way, you can retrieve the individual objective values and the shadow prices of the constraints.
Does this help?
Best regards,
Marika0 -
Yes, that helps! Thanks a lot!
Best wishes,
Jonas0
Please sign in to leave a comment.
Comments
7 comments