Dynamic update of model constrains and objective function parameter

2,238 views
Skip to first unread message

Giacomo Pallucca

unread,
Apr 3, 2017, 8:23:10 AM4/3/17
to Gurobi Optimization

I'm looking for some help to optimize my code execution.


I build up a Model Predictive Control and I use Gurobi QP solver to solve the QP problem on-line.


For each sample time the code create a new model, variables and constrains. The structure of the problem doesn't change during a single simulation, but change the value of coefficients of constraints and objective function.


I want to find a way to update this coefficients due to reduce the time execution of the solver.


Now more than 60% of time execution was passed in build new constrain each time.


In the code example, the QP problem is:

Objective function: x^t H x + F^t x ||| Constrains: A x <= b

F,A and b are matrix that change each time step.


import numpy as N
import gurobipy as gpy
m=gpy.Model()
H=mpcSim.H
A_cons=N.asarray(mpcSim.A_cons)
b=N.asarray(mpcSim.b)
F=mpcSim.F

n_cons,n_stato=A_cons.shape

x={}
for ii in range(n_stato):
    x[ii]=m.addVar(lb=-1e20,ub=1e20,name='x{}'.format(ii))

m.update()    

for ii in range(n_cons):
    m.addConstr(gpy.quicksum(A_cons[ii,jj]*x[jj] for jj in range(n_stato)), gpy.GRB.LESS_EQUAL, b[ii,0],name='Const{}'.format(ii))
m.update()

obj1=gpy.quicksum(gpy.quicksum(H[ii,jj]*x[ii] for ii in range(n_stato))*x[jj] for jj in range(n_stato))
obj2=gpy.quicksum(F[ii,0]*x[ii] for ii in range(n_stato))


m.setObjective(obj1+obj2)

m.optimize()


Thanks in advance,

Jack

des...@gurobi.com

unread,
Apr 17, 2017, 6:45:01 PM4/17/17
to Gurobi Optimization

Jack,

You don't need to create a model every time. You can create one model and then change the coefficients.

To change a coefficient in the coefficient matrix you can use the following function::

http://www.gurobi.com/documentation/7.0/refman/py_model_chgcoeff.html

To change the linear objective coefficients you have to change the obj variable attribute:

http://www.gurobi.com/documentation/7.0/refman/obj.html#attr:Obj

However, changing the coefficients of a quadratic objective is a bit more complex.

To do this you would need to do the following steps:
1. Call Model.getObjective() to get the QuadExpr

http://www.gurobi.com/documentation/7.0/refman/py_model_getobjective.html

2. Call QuadExpr.remove() to remove the term

http://www.gurobi.com/documentation/7.0/refman/py_quadexpr_remove.html

3. Call QuadExpr.addTerms() to add the new term

http://www.gurobi.com/documentation/7.0/refman/py_quadexpr_addterms.html

4. Finally, call Model.setObjective() to replace the objective

http://www.gurobi.com/documentation/7.0/refman/py_model_setobjective.html

Note that the optimization should be faster as well, as  Gurobi will do a warm start. That is, it will start from the optimal solution of the previous model instead of starting from beginning ( provided you set the parameter Method=0 or 1).

I hope this helps

Amal de Silva
Gurobi Optimization

Rabab Haider

unread,
Nov 20, 2018, 12:35:21 AM11/20/18
to Gurobi Optimization
Hello there,

I've been looking into creating a few Gurobi models, keeping them in memory, and then modifying & running them as needed (I have a few models I need to solve together over numerous iterations). However, I am using Matlab, and I cannot find any documentation showing if this is possible outside of the Python/C interfaces, and how to do this.

Could you provide any suggestions/direction? I am using Gurobi 7.52

fiona H

unread,
Nov 26, 2018, 6:28:51 PM11/26/18
to Gurobi Optimization
Hi Amal,

I got a similar problem as Jack's, what if I want to change the 'b' in constraint: Ax <= b, what function can I use to do that?

Thanks,
Fiona

在 2017年4月18日星期二 UTC+2上午12:45:01,des...@gurobi.com写道:

Michael Winkler

unread,
Nov 27, 2018, 5:48:13 AM11/27/18
to Gurobi Optimization
Hi Fiona,

do you want to change the right hand side (b) just for some constraint(s) or the whole matrix? For the former you might want to directly use

c1 = model.addConstr(x + y >= 1.0, "c1")
c1.rhs = 2.0

if you know your constraints. Otherwise you might want to use the setAttr() method to chnage multiple/all right hand sides.


model.setAttr("rhs", conss, values)

where conss is a list of your constraints where you want to change the right hand side (e.g.,  conss=m.getConstrs() would be all) and values is a list of new right hand side values. See here https://www.gurobi.com/documentation/8.1/refman/py_model_setattr.html.

Best,
Michael

Robert Luce

unread,
Nov 27, 2018, 6:35:40 AM11/27/18
to Gurobi Optimization
Hello Rabab,

you can keep as many model structs in memory as you'd like, and modify them as you need.  For example...

% Read a example model, comes along with Gurobi installation
model
= gurobi_read('afiro.mps.bz2');
% Solve it, print objective value
result
= gurobi(model);
disp
(result.objval);
% Save a copy of original model
model_org
= model;
% Fix some variable to some value
model
.lb(5) = 15.0;
model
.ub(5) = 15.0;
% Solve again, objective value now larger
result
= gurobi(model);
disp
(result.objval);

Robert

Fiona Huang

unread,
Nov 27, 2018, 3:54:26 PM11/27/18
to gur...@googlegroups.com
Hi Micheal,

Thank you! This function is super useful for me!

Best,
Fiona

--

---
You received this message because you are subscribed to a topic in the Google Groups "Gurobi Optimization" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/gurobi/89FfTQo48qg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to gurobi+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages