Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use cvxpy to abstract MILP solver #19

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

r-barnes
Copy link

This switches the code from using Gurobi to using cvxpy as an abtraction for the MILP solver.

Upsides:

  • It becomes possible to use the MILP approach if you (like me) don't have a copy of Gurobi.
  • The open source CBC solver seems to work well, but a person could use Gurobi, FICO XPRESS, GLPK MI, or any of a number of other solvers.
  • cvxpy has an elegant interface which allows this switch with fairly minimal code changes.

Downsides:

  • cvxpy takes some time to compile problems into a form it can pass to the solver (eg, CBC). In the case of the test code, this took 83s on my pretty powerful machine. Once compiled, a problem can be quickly resolved by changing parameters, though pycombina doesn't seem to have this eventuality built in.

@mirhahn
Copy link
Contributor

mirhahn commented Dec 27, 2021

Hi @r-barnes,

The downside of 83 seconds of one-time setup seems a bit steep for something as minor as a CIA solver. They are not really meant to have a huge footprint. Real-time viability is something of a factor with CIA solvers. I am not familiar with CVXPY's concept of parameterized problems but I have a suspicion that we may have to recompile these problems whenever we change the number of time intervals. Do you know whether this is the case?

Regardless, this seems to be a good setting for a metaclass. We could split up CombinaMILP into two classes called, for instance, CombinaGurobi and CombinaCVXPY with a (largely) shared public interface. We could then make CombinaMILP into a metaclass with constructor signature __new__(*args, solver:str='gurobi', **kwargs) which would select the returned object's type based on the solver parameter.

In this way, the Gurobi interface with its faster setup time could be preserved, the public-facing default behavior of CombinaMILP would not change, and CVXPY would become available as an alternative. In principle the default value of the solver parameter could be selected dynamically based on package availability.

If you do not want to make that type of change to your own work, I can bring my fork up to date and do some prep work there. What do you think?

Edit: I have eyeballed this change and filed a pull request for your branch. Have a look and see whether you like it.

@r-barnes
Copy link
Author

@mirhahn : I've tried using PuLP instead in #20 and find that it has a very short (0.64s) setup time, but that the problem it generates takes longer to solve. In #21 I suggest most of the time-to-solution is taken up exploring symmetries. If we find a way to break those symmetries, PuLP's faster preprocessing time probably makes it a better choice for abstraction.

I am happy to adapt either #19 or #20 based on your suggestions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants