In multi-objective optimization, not all Model attributes are available. You can use callbacks to store these values (and others) and print them manually when the optimization is finished:
def mycallback(model, where):
if where == GRB.Callback.MIPSOL:
model._bound = model.cbGet(GRB.Callback.MIPSOL_OBJBND)
model._best = model.cbGet(GRB.Callback.MIPSOL_OBJBST)
elif where == GRB.Callback.MULTIOBJ:
model._bounds[model.cbGet(GRB.Callback.MULTIOBJ_OBJCNT) - 1] = model._bound
model._bests[model.cbGet(GRB.Callback.MULTIOBJ_OBJCNT) - 1] = model._best
model._bounds = [None]*NObjectives
model._bests = [None]*NObjectives
model.optimize(mycallback)
Another alternative is to parse the status message that is printed after optimizing each objective:
def mycallback(model, where):
if where == GRB.Callback.MESSAGE:
msg = model.cbGet(GRB.Callback.MSG_STRING)
if msg.startswith('Best objective'):
model._bests.append(float(msg.split()[2].rstrip(',')))
model._bounds.append(float(msg.split()[5].rstrip(',')))
model._bounds = []
model._bests = []
model.optimize(mycallback)
If you combine blended and hierarchical objectives, as described in the section Working with Multiple Objectives of our reference manual, you can also resort to callbacks to report the value of all individual objective functions independently after each optimization run. The callback function should retrieve the current solution and go through each objective index to manually compute the corresponding objective value (you may need to store the objective coefficients as a user-defined attribute of the model object):
def mycallback(model, where):
if where == GRB.Callback.MULTIOBJ:
variables = {var.varName: var for var in model.getVars()}
variables = model.cbGetSolution(variables)
for obj_idx in range(model.NumObj):
obj_val = model._objcoeffs[obj_idx]["c"]
for var_name, var_val in variables.items():
obj_val += var_val*model._objcoeffs[obj_idx][var_name]
print(f"Obj: {obj_idx}; value: {obj_val}")
# Define optimization model
...
# Add user-defined attribute needed in the callback
model.update()
d = {}
for i in range(model.NumObj):
model.params.objNumber = i
d[i] = {}
d[i]["c"] = model.getObjective(index=i).getConstant()
for var in model.getVars():
d[i][var.varName] = var.objN
model._objcoeffs = d
del d
model.optimize(mycallback)
Comments
0 comments
Article is closed for comments.