Pyomo / pyomo

An object-oriented algebraic modeling language in Python for structured optimization problems.
https://www.pyomo.org
Other
1.99k stars 512 forks source link

Sequential Decomposition tool defaults to MIP approach for determining tear streams. #1483

Open andrewlee94 opened 4 years ago

andrewlee94 commented 4 years ago

An IDAES user brought this to my attention, and I thought that it would be worth raising for discussion.

When using the sequential decomposition tool to determine tear streams in a network, if the user does not set the options.select_tear_method argument, the tool defaults to using the MIP approach which requires CPLEX. In cases where a user does not have CPLEX, then they receive the obvious error that it could not be found (traceback at end).

It strikes me that the heuristic approach would be a safer option to use as the default, as it does not rely on an external solver dependency. For novice users, this would work out-of-the-box without them needing to know about the deeper options (and not give the impression that they need an MILP solver). At the very least, the error message the user gets back needs to let them know that there are alternatives to using CPLEX that they can use (the error message received implies you need CPLEX to use the SD tool).

WARNING: Could not locate the 'cplex' executable, which is required for solver
    cplex
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-7-21906b656554> in <module>
     96 #seq.options.tear_method = "Wegstein"
     97 #seq.options.iterLim = 5
---> 98 seq.run(m, function)
     99 
    100 # Solve the flowsheet using ipopt

~\AppData\Local\Continuum\anaconda3\envs\idaes\lib\site-packages\pyomo\network\decomposition.py in run(self, model, function)
    294             G = self.create_graph(model)
    295 
--> 296         tset = self.tear_set(G)
    297 
    298         if self.options["run_first_pass"]:

~\AppData\Local\Continuum\anaconda3\envs\idaes\lib\site-packages\pyomo\network\decomposition.py in tear_set(self, G)
    949             else:
    950                 raise ValueError("Invalid select_tear_method '%s'" % (method,))
--> 951         return self.cacher(key, fcn, G)
    952 
    953     def arc_to_edge(self, G):

~\AppData\Local\Continuum\anaconda3\envs\idaes\lib\site-packages\pyomo\network\decomposition.py in cacher(self, key, fcn, *args)
    918         if key in self.cache:
    919             return self.cache[key]
--> 920         res = fcn(*args)
    921         self.cache[key] = res
    922         return res

~\AppData\Local\Continuum\anaconda3\envs\idaes\lib\site-packages\pyomo\network\decomposition.py in fcn(G)
    943                                             self.options["tear_solver"],
    944                                             self.options["tear_solver_io"],
--> 945                                             self.options["tear_solver_options"])
    946             elif method == "heuristic":
    947                 # tset is the first list in the first return value

~\AppData\Local\Continuum\anaconda3\envs\idaes\lib\site-packages\pyomo\network\decomposition.py in select_tear_mip(self, G, solver, solver_io, solver_options)
    778         if not opt.available(exception_flag=False):
    779             raise ValueError("Solver '%s' (solver_io=%r) is not available, please pass a "
--> 780                              "different solver" % (solver, solver_io))
    781         opt.solve(model, **solver_options)
    782 

ValueError: Solver 'cplex' (solver_io=None) is not available, please pass a different solver
qtothec commented 4 years ago

The other option is to use cbc or glpk as the default mip solver.

andrewlee94 commented 4 years ago

@qtothec That would still require the user to install those solvers (which is admittedly not hard, but still an extra dependency).

jsiirola commented 4 years ago

As Pyomo is an optimization modeling framework, I am somewhat partial to having the default approach be optimization-based. That said, I think it would be a good PR to change the default solver to None, and then inside select_tear_mip if it is None, then search through (gurobi,cplex,xpress,cbc,gplk) and select the first one that is available.

andrewlee94 commented 4 years ago

@jsiirola I happen to agree on your point about Pyomo being an optimisation tool. Following on from your idea about searching a list of solvers, would it be possible to have the final option be a fall back to the heuristic approach (probably with a warning message)?

carldlaird commented 4 years ago

@jsiirola @andrewlee94 I think we should default to the heuristic. (my opinion).

jsiirola commented 4 years ago

@andrewlee94, I am less keen to automatically change the method: the solution the user gets shouldn't be too dependent on the MIP solver, but switching from MIP to Heuristic will change things. I think I would propose throwing a more informative error message if tear_solver was None and none of the MIP solvers that we looked for are available.

@carldlaird, to clarify, do you think the default for the SD tool in Pyomo should be a heuristic, or do you think that the IDAES default use of the SD tool should be in heuristic mode?