TypeError: bad operand type for unary -: 'GenExprNorm'
OngoingHi,
I am trying to code an objective function that is something like:
x * S - k ||S - h||_1
And I tried by producing code part of which is reported below.
diff = scr - h
vars_norm = model.addMVar((1,), vtype=gb.GRB.CONTINUOUS, name="norm_vars")
model.setObjective(x @ scr - k * vars_norm,
gb.GRB.MAXIMIZE)
model.addConstr(vars_norm == gb.norm(diff, 1.0), name="norm_eq")
In particular:
scr is <gurobi.MLinExpr, 57 rows, 57 cols, 92 nnz>
h is a list object of length 57
x is <(57,) matrix variable>
k is an Int
After executing the addConstr line the program launch the error below:
TypeError: bad operand type for unary -: 'GenExprNorm'
Can someone explain why?
Thank you in advance
-
Official comment
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum, or try Gurobot, our chatbot interface offering instant, expert-level support. -
Hi Giovanni,You need to change the constraint as below to assign the GenExprNorm to a Gurobi Var object and not a Gurobi MVar Object.
model.addConstr(vars_norm[0] == gp.norm(diff, 1.0), name="norm_eq")
Furthermore, you need to define \(\texttt{diff}\) as MVar objects, otherwise, you will get the error that"TypeError: object of type 'MLinExpr' has no len()".diff = model.addMVar(57, name="diff_vars")
model.addConstr(diff == scr - h, name="diff_constrs")Best regards,Maliheh0 -
Hi Maliheh,
Thank you very much. It seems to work now.
I have a couple of questions related to your answer still:
1. Doing
model.addConstr(vars_norm[0] == gp.norm(diff, 1.0), name="norm_eq")
or doing
vars_norm = model.addVar(vtype=gb.GRB.CONTINUOUS, name="norm_vars")
model.addConstr(vars_norm == gp.norm(diff, 1.0), name="norm_eq")Would it work the same?
2.
diff = model.addMVar(57, name="diff_vars")
diff = model.addMVar((57,), name="diff_vars")The above lines of code work in the same way? The first one returns an error since it expects a tuple for that argument
Thank you again
Kind regards
Giovanni
0 -
Hi Giovanni,
- Since you are subtracting \(\texttt{k * vars_norm}\) from MQuadExpr \(\texttt{x @ scr}\) in the objective function, \(\texttt{k * vars_norm}\) should be a Gurobi matrix expression and that is why \(\texttt{vars_norm}\) needs to be an MVar object. If you did not have this part in the objective function, you could have defined \(\texttt{vars_norm}\) as a Var object.
- Which Gurobi version are you using? Both works when creating a 1-D array of variables (see the example at the end of Model.addMVar() documentation page). I tested this and I can use both in Gurobi version 9.5.0.
Best regards,
Maliheh
0 -
Hi Maliheh,
1. Ok all clear now!
2. I am using 9.5.0 too and it actually yield only a syntax warning, not an error.
Thank you very much once again!
Bests,
Giovanni
0
Post is closed for comments.
Comments
5 comments