Closed ZedongPeng closed 2 years ago
I have been trying to favor conservative and safe defaults. I don't want someone to miss a warning and proceed thinking they have a solution. However, this is definitely worth a design discussion. Do others have thoughts on this?
I have an opinion regarding this. Although most people use Pyomo models to solve feasible problems, and a guarantee of infeasibility often means a modeling mistake; there is a considerable number of cases where infeasible solutions are valid solutions. One example is using a MIP solver to address a SAT problem, infeasible is a valid answer to this problem. It seems that having a runtime error for infeasibility is too conservative, and a warning might be enough.
Even though there is a mechanism to say don't throw an error?
What if we set all of the variable values to None
by default when a feasible solution is not found? I think that would take care of my concerns, and I would be fine without an error.
My point is that infeasible problems are not errors per se, most of the time they might mean modeling errors, but sometimes you are expecting your problem to be infeasible. Consider algorithms that take into account the infeasibility of problems to do stuff (e.g., Benders decomposition). Would then obtaining an infeasible problem (which is alright and even expected) lead to the same error as dividing by zero?
The intent of the error is not to say that there is a problem with the model. The intent of the error is to say that a solution cannot be loaded into the model. By default, all solvers automatically load the solution into the model as part of the call to solve
. If there is no feasible solution, how do we reconcile these two things? I'm liking the None
idea for the moment.
The None
idea also sounds good to me.
By the way, I think it's always good to keep APPSI consistent with the base solver interface.
https://github.com/Pyomo/pyomo/blob/a82c55771f38b6a5a689c4a40fe0b9040503c320/pyomo/opt/base/solvers.py#L604-L634
For the current RuntimeError
implementation, I can use try
and except
to handle it.
@ZedongPeng, can you elaborate on your last comment about keeping Apps consistent with the base solver interface? Are you referring to the point that the non-appsi solvers do not raise an error?
You do not need a try-except block. Just set load_solution
to False
. See this example: https://pyomo.readthedocs.io/en/stable/library_reference/appsi/appsi.base.html#pyomo.contrib.appsi.base.Results
At the dev call today, there was consensus that we need to be very conservative here. The default behavior should be to raise an error if the solver did not terminate optimally. However, we did discuss a more flexible mechanism for configuring this behavior (rather than the single load_solution
flag).
@ZedongPeng, can you elaborate on your last comment about keeping Apps consistent with the base solver interface? Are you referring to the point that the non-appsi solvers do not raise an error?
You do not need a try-except block. Just set
load_solution
toFalse
. See this example: https://pyomo.readthedocs.io/en/stable/library_reference/appsi/appsi.base.html#pyomo.contrib.appsi.base.Results
Yes. I mean that the non-appsi solvers do not raise an error.
Moreover, if I call CPLEX through APPSI appsi.solvers.Cplex()
, the result returned is not in same format as non-appsi solvers, which has problem, solver and solution. (This is not a problem since SolverFactory('appsi_cplex')
will return the same format result.)
opt = appsi.solvers.Cplex()
opt.solve()
doesn't have the tee
arguments. We need to set opt.config.stream_solver = True
.
Summary
Currently in APPSI, if the problem is infeasible and
config.load_solution=True
, aRuntimeError
will be raised.For example, in appsi/solvers/cplex.py, there are several places that report a
RuntimeError
.https://github.com/Pyomo/pyomo/blob/b82083bed71bffdb549fca41c18729e75b9b8b53/pyomo/contrib/appsi/solvers/cplex.py#L300-L305
https://github.com/Pyomo/pyomo/blob/b82083bed71bffdb549fca41c18729e75b9b8b53/pyomo/contrib/appsi/solvers/cplex.py#L317-L319
https://github.com/Pyomo/pyomo/blob/b82083bed71bffdb549fca41c18729e75b9b8b53/pyomo/contrib/appsi/solvers/cplex.py#L375-L377
Considering that infeasible problem happens a lot and
config.load_solution=True
by default, is it too serious to report a RuntimeError in this case? I think a warning or a debug log might be better. If we call_cplex_shell
orcplex_direct
, no error will be reported if the problem is infeasible.