coin-or / python-mip

Python-MIP: collection of Python tools for the modeling and solution of Mixed-Integer Linear programs
Eclipse Public License 2.0
525 stars 92 forks source link

`model.write` output invalid lp file #130

Closed vang1ong7ang closed 4 years ago

vang1ong7ang commented 4 years ago

Describe the bug A clear and concise description of what the bug is.

if you call something like model.add_constr(linexpr >= 0), actually the linexpr is a constant LinExpr with value 0, and then call model.write(lpfile), you will see a line constr(0): >= -0 in the lp file, which makes the lp file invalid.

To Reproduce Steps to reproduce the behavior please include attached any files needed to reproduce the error. We can only help you if we can reproduce the error ourselves and debug.

from mip import Model

m = Model()
x = m.add_var()

# sometimes y is indeed a constant LinExpr 0
# for example
# y = x - x
# y = xsum([])
# ...

y = x - x
m.add_constr(y >= 0)
m.objective = x
m.write('out.lp')
\Problem name: 

Minimize
OBJROW: var(0)
Subject To
constr(0):  >= -0
Bounds
End

Expected behavior A clear and concise description of what you expected to happen.

Desktop (please complete the following information):

Additional context Add any other context about the problem here.

tuliotoffolo commented 4 years ago

I talked with @h-g-s about this. We both agree that we shouldn't allow creating constraints with empty linear expressions. Therefore, the code below should throw an InvalidLinExpr exception. Something like "An empty linear expression cannot be used as a constraint".

y = x - x
m.add_constr(y >= 0)

I will update the code to raise the exception in such cases.

tuliotoffolo commented 4 years ago

Some people may be currently using empty linear expressions to create constraints in their models... As to avoid problems, I will leave this issue open for the moment. Concerning the LP file, I should mention that it is generated by the solver itself.

vang1ong7ang commented 4 years ago

I talked with @h-g-s about this. We both agree that we shouldn't allow creating constraints with empty linear expressions. Therefore, the code below should throw an InvalidLinExpr exception. Something like "An empty linear expression cannot be used as a constraint".

y = x - x
m.add_constr(y >= 0)

I will update the code to raise the exception in such cases.

But actually, people may not intentionally create empty linear expressions. Someone may use xsum or some other operations and accidentally an empty linear expression is created.

For example, if a model is created with the following constraints where a, b, c, d are rational numbers provided from user input.


a, b, c, d = get_user_input()

m = Model()

# ...

s = m.add_var()
t = m.add_var()
x = a * s + b * t
y = c * s + d * t
m.add_constr(x + y >=0)

# ...

Users may provide a = 1; b =1; c = 1; d = 1; or a = 1; b =1; c = -1; d = -1;.

Anyway, handling empty constraints or just raising an exception are both acceptable for users.