Change objective function during optimization
OngoingWe cannot use a certain type of cut with Gurobi because it requires the replacement of a part of the objective function in the callback. It would be cool if there was some "on-your-own-risk"-way of doing this, maybe a parameter for enabling this and otherwise having Gurobi complain that this is a terrible idea?
-
Replacing parts of the objective function would mean that Gurobi has to process the change through the whole B&B tree thus far and possibly adjust cuts and all relevant datastructures, resulting in a significant workload. This may in worst case even mean to throw away the whole B&B tree progress. Thus, we currently do not plan to implement this feature.
I understand, that in some cases it might be possible that the state of the tree may remain unchanged but this seems to be a very specific situation. You could try to terminate the solution process, save the solution point, add the cut, adjust the objective function, provide the saved solution point as a MIP start, and re-optimize. This might not 100% reflect your idea but it might be just good enough.
Best regards,
Jaromił0 -
Hi Jaromil, a have a similar problem.
I need to delete and insert the same objective function during each iteration in the loop of the rolling horizon. I coded my model in Pyomo framework and used the Gurobi Persistent to convert my model to Gurobopy. This documentation (https://pyomo.readthedocs.io/en/stable/advanced_topics/persistent_solvers.html ) states, "We can also add or remove variables, constraints, blocks, and objectives.". But the GurobiPersistent class hasn´t implemented these methods.
My objective function is presented following:
model.exprobj = pyo.Expression()
if RestrEquilibrioVarietal == 'Soft1':
if RestrEquilibrioEtario == 'Soft1':
model.exprobj = sum(sum(sum(theta[v,l,t] for v in model.set_V) for l in model.set_L) for t in model.set_T) \
- sum( PenEqVar[t] * sum(sum(ViolaUmin[v,l,t]+ViolaUmax[v,l,t] for v in model.set_V) for l in model.set_L) for t in model.set_T) \
- sum( PenEqIdade[t] * sum(ViolaWmin[g,t]+ViolaWmax[g,t] for g in model.set_G) for t in model.set_T) \
- sum( PenMaxVar[t] * sum( ViolaVmax[f,t] for f in model.set_F ) for t in model.set_T )elif RestrEquilibrioEtario == 'Soft2':
model.exprobj = sum(sum(sum(theta[v,l,t] for v in model.set_V) for l in model.set_L) for t in model.set_T) \
- sum( PenEqVar[t] * sum(sum(ViolaUmin[v,l,t]+ViolaUmax[v,l,t] for v in model.set_V) for l in model.set_L) for t in model.set_T) \
-PenEqIdade[0] * sum(ViolaWmin[g]+ViolaWmax[g] for g in model.set_G) \
- sum( PenMaxVar[t] * sum( ViolaVmax[f,t] for f in model.set_F ) for t in model.set_T )else:
model.exprobj = sum(sum(sum(theta[v,l,t] for v in model.set_V) for l in model.set_L) for t in model.set_T) \
- sum( PenEqVar[t] * sum(sum(ViolaUmin[v,l,t]+ViolaUmax[v,l,t] for v in model.set_V) for l in model.set_L) for t in model.set_T) \
- sum( PenMaxVar[t] * sum( ViolaVmax[f,t] for f in model.set_F ) for t in model.set_T )elif RestrEquilibrioVarietal == 'Soft2':
if RestrEquilibrioEtario == 'Soft1':
model.exprobj = sum(sum(sum(theta[v,l,t] for v in model.set_V) for l in model.set_L) for t in model.set_T) \
-PenEqVar[0] * sum(ViolaUmin[v]+ViolaUmax[v] for v in model.set_V) \
- sum( PenEqIdade[t] * sum(ViolaWmin[g,t]+ViolaWmax[g,t] for g in model.set_G) for t in model.set_T) \
- sum( PenMaxVar[t] * sum( ViolaVmax[f,t] for f in model.set_F ) for t in model.set_T )elif RestrEquilibrioEtario == 'Soft2':
model.exprobj = sum(sum(sum(theta[v,l,t] for v in model.set_V) for l in model.set_L) for t in model.set_T) \
-PenEqVar[0] * sum(ViolaUmin[v]+ViolaUmax[v] for v in model.set_V) \
-PenEqIdade[0] * sum(ViolaWmin[g]+ViolaWmax[g] for g in model.set_G) \
- sum( PenMaxVar[t] * sum( ViolaVmax[f,t] for f in model.set_F ) for t in model.set_T )else:
model.exprobj = sum(sum(sum(theta[v,l,t] for v in model.set_V) for l in model.set_L) for t in model.set_T) \
-PenEqVar[0] * sum(ViolaUmin[v]+ViolaUmax[v] for v in model.set_V) \
- sum( PenMaxVar[t] * sum( ViolaVmax[f,t] for f in model.set_F ) for t in model.set_T )
else:if RestrEquilibrioEtario == 'Soft1':
model.exprobj = sum(sum(sum(theta[v,l,t] for v in model.set_V) for l in model.set_L) for t in model.set_T) \
- sum(PenEqIdade[t] * sum(ViolaWmin[g,t]+ViolaWmax[g,t] for g in model.set_G) for t in model.set_T) \
- sum( PenMaxVar[t] * sum( ViolaVmax[f,t] for f in model.set_F ) for t in model.set_T )
elif RestrEquilibrioEtario == 'Soft2':model.exprobj = sum(sum(sum(theta[v,l,t] for v in model.set_V) for l in model.set_L) for t in model.set_T) \
- PenEqIdade[0] * sum(ViolaWmin[g]+ViolaWmax[g] for g in model.set_G) \
- sum( PenMaxVar[t] * sum( ViolaVmax[f,t] for f in model.set_F ) for t in model.set_T )else:
model.exprobj = sum(sum(sum(theta[v,l,t] for v in model.set_V) for l in model.set_L) for t in model.set_T) \
- sum( PenMaxVar[t] * sum( ViolaVmax[f,t] for f in model.set_F ) for t in model.set_T )model.obj = pyo.Objective(expr= model.exprobj, sense = pyo.maximize)
opt = pyo.SolverFactory('gurobi_persistent')
opt.set_instance(model)In each iteration of the rolling horizon loop, I need to delete and insert the same model.obj (objective function).
How I can implement this?
0
Please sign in to leave a comment.
Comments
2 comments