Odd behaviors with NA in the objective function
AnsweredHi, I am trying to upgrade from gurobi 9.5.2 to 11.0.3, and by accident, I found some strange behaviors when I have NA in the objective function. Here is a reproducible example:
x = model.addMVar(2, name='x', lb=[0, -1], ub=[0, 1])
alpha = np.array([np.nan, 1])
obj = alpha @ x
(basically, the coefficient of the first element of x is NA, but the range of that is 0). obj now looks like this:
<MLinExpr () > array( nan x[0] + x[1])
after model.optimize(), I now get the "correct" solution,
x.X is
array([0., 1.])
model.objVal
1.0
On the other hand, obj.getValue()
array(nan)
I mean, in this case, having an NA is clearly my fault, and it is debatable whether the "objective" should be NA or 1; but I find it a bit strange that the two are not the same... This is the first issue I'd like to mention.
A second issue is that if I save this model to an mps file, and load it back, now miraculously the NA term disappears! (And an MLinExpr obj becomes LinExpr, though it doesn't really bother me):
<gurobi.LinExpr: x[1]>
A third issue is that in the original model (without round tripping to an mps file), if I try to add another expression, then it crashes (well, whether it crashes depends on the subsequent expression). Here is an example:
beta = model.addMVar(2, name='beta', lb=[-1, -1], ub=[1, 1])
obj = obj - beta.sum()
model.update()
model.setObjective(obj, gurobipy.GRB.MAXIMIZE)
--------------------------------------------------------------------------- GurobiError Traceback (most recent call last) Cell In[19], line 2 1 model.update() ----> 2 model.setObjective(obj, gurobipy.GRB.MAXIMIZE) File src/gurobipy/model.pxi:1537, in gurobipy.Model.setObjective() GurobiError: Element 0 of a double array is Nan or Inf.
In the old version 9.5.2, it didn't crash here, and goes on like the first paragraph. Personally, I think crashing is better. However, it would really help me if it crashes as soon as it sees an NA in the first place, rather than crashing it here! It took me two days to understand where the issue was (I am not an expert in gurobi, and I find reading a large mps file very hard, otherwise I would have figured out what was going on faster...)
-
Actually, even if the range of x[0] is none-empty, it still is ignored in mode.objVal.
0 -
Another point is that if instead of doing
obj = obj - beta.sum()
I do
obj = obj - beta[0] - beta[1],
then the code does not crash. Again, I am not saying that this is wrong in itself, just that it confuses the debugging effort.
0 -
Hi Ying,
Thanks for reporting this. I agree with you that this is not the right behaviour, really any `nan` values in input data should result in an error when building a model. Evidently there is some inconsistent behaviour: for some cases, gurobipy will raise an exception for invalid data. For some others, it will ignore the invalid coefficients (which are then essentially treated as zero when solving a model or writing it to a file).
We will fix this in a future release. In the meantime, the best approach is to validate your data beforehand, for example using numpy's isnan.
0
Please sign in to leave a comment.
Comments
3 comments