• Gurobi Staff

Hi Jonathan,

Can you try calling grbModel.update() before changing the coefficient? You can read more about this in the "Lazy Updates" section here. Essentially, if you want to immediately access a variable/constraint attribute or change some part of the model, you should first update the model.

If this doesn't work, could you post a small working code example that reproduces the problem? Thanks!

Eli

Yes, I did update the model first.  I'll try to post a self-contained example soon.

Here is a 12-line program that produces the same error.  Possibly I am doing something really dumb, but it is my first time with this API.  Optimizing the model instead of updating doesn't change the error.

Thanks!  -- Jonatha

import numpy
import gurobipy as gp
from gurobipy import GRB

n = 10

m = gp.Model()
grbx = m.addMVar(shape=n, lb=-1.0, ub=1.0, vtype=GRB.CONTINUOUS, name="grbx")
randomMatrix = numpy.random.rand(20,10)
Q = numpy.transpose(randomMatrix) @ randomMatrix
m.setObjective(0.5*(grbx @ Q @ grbx))
constr = m.addConstr(grbx[0] + grbx[1] + grbx[2] <= 1.0)
m.update()

m.chgCoeff(constr,grbx[1],-2.0)

• Gurobi Staff

Hi Jonathan,

Ah, yes, you're right that this is because you are passing an $$\texttt{MVar}$$ object instead of a $$\texttt{Var}$$ object. I missed that in my first (hasty) reading of your post. I don't believe there is an analogous method for $$\texttt{MVar}$$ objects. I'll look into this and get back to you.

Thanks,

Eli

OK, thanks!  Please let me know what you find out.

Setting up my objective function with only scalar variables would be hellish.  I suppose that I could make big pile of scalar variables, each with an equality constraint to an element of the matrix variable.  That would not be pretty.  Or I guess I could simply delete all my constraints and then add in new ones.

I have to solve a bunch of QP problems, each of which some different variable bounds and linear constraint coefficients.

• Gurobi Staff

Hello Jonathan,

as written by Eli there currently is no way to change coefficents w.r.t. an Mvar object, but I have registered this in our backlog of future improvements to the matrix-friendly API.  Your suggestion to delete the old constraints, modify the coefficients on the ndarray level, and add them back to the model seems to be the most practical workaround to me.

Robert

OK, thanks for checking.  I will just delete the constraints and add back modified ones.  I suspect that will be slow, but this is a prototype, proof-of-concept implementation, so its speed is not absolutely critical.

Dear Robert and Eli,

does this feature (change coefficients w.r.t. an Mvar object) already exist in the latest version of Gurobi (9.1)?

Thank you!

Chris.

• Gurobi Staff

Unfortunately not. However, there is an easy workaround available in Gurobi 9.1. Namely, you can use MVar.tolist() to convert MVar objects to Var objects for use in Model.chgCoeff(). Similarly, you can convert MConstr objects to Constr objects with MConstr.tolist(). For example:

import numpy as npimport gurobipy as gpm = gp.Model()x = m.addMVar(shape=(3,), name='x')a = np.array([1.0, 2.0, 3.0])# Add constraint x[0] + 2 x[1] + 3 x[2] <= 1c = m.addConstr(a @ x <= 1)m.write('model1.lp')# Change to 5 x[0] + 2 x[1] + 3 x[2] <= 1m.chgCoeff(c.tolist()[0], x.tolist()[0], 5)m.write('model2.lp')
• Gurobi Staff

That said, the workaround should no longer be necessary starting in the next feature release after 9.1, where you will be able to just do

m.chgCoeff(c[0], x[0], 5)

This works because indexing an MVar/MConstr will yield a Var/Constr object instead of a (1,) slice.

Thank you both! I am looking forward to the new release but for the time being Eli's suggested work-around will do it too.

• Gurobi Staff

Hi Chris,

Gurobi 9.5 was recently released. Included in this release is a new feature where indexing an MVar/MConstr returns a Var/Constr object.

We hope this fix works well for you. Please let us know if you see any other issues using this.

Best regards,

Maliheh