oemof / oemof-solph

A model generator for energy system modelling and optimisation (LP/MILP).
https://oemof.org
MIT License
297 stars 126 forks source link

Start values could be provided to the solver #759

Open jokochems opened 3 years ago

jokochems commented 3 years ago

At the user & dev meeting in Spring 2021 it was brought up that providing the solver with start values may increase computation speed. This is especially true if you have to resolve a complicated model with minor modification often times (like in a sensitivity analysis) and probably most relevant for nonconvex (MILP) models.

It seemed that from the developer side, there is no urgent need to have that feature though there is some general interest.

jokochems commented 3 years ago

Without having a deeper look into it, this should be possible by passing down values to the initialize attribute of pyomo variables, see the pyomo docs on Variables. This should actually be not so hard to do.

Finding appropriate start values and mapping them to your components and objects could potentially be harder to achieve. In my personal opinion, it wouldn't make so much sense to provide this feature without the option to extract suitable start values.

simnh commented 3 years ago

Yes pyomo supports this. Finding values will indeed by not easy. The easiest way would be to use values from solved similar models, where the pyomo model instance with results values is used. For example, if only the objective function is replaced, this could be done building the new objective, keeping the rest of the (solved model). However, if new components enter or new constraints due to other paramerisation it might be difficult.

The main problem I see is that there is no direct link between the values / parameters inside components and variables / parameters inside the model. Therefore, in any way it would include working on the pyomo-model instance.

On the other hand: it should be easy add a attribute to all flow variables, i.e. such as "value" , which is then used when the model is build. that can be done for the investment variables etc as well...

We actually do this already for the components (here, where we fix the values (e.g. for modelling must-run or renewables).

Without the .fix() call, I think that values would be used as start values (if gurobi / cplex is used and the warmstart agrument)

jokochems commented 3 years ago

I totally agree with you, @simnh. That is exactly what I had in mind in terms of difficulties. You need a remapping back from your model results to the pyomo variables. This could also be used to speed up rolling horizon computations because you wouldn't have to rebuild your model in each iteration.

We actually do this already for the components (here, where we fix the values (e.g. for modelling must-run or renewables).

Without the .fix() call, I think that values would be used as start values (if gurobi / cplex is used and the warmstart agrument)

I don't know if I get your point here, but If I'm not mistaken, this is a bit different. Effectively, calling .fix() turns variables into (fixed) model parameters. This is probably not what you want when it comes to providing start values since you are still seeking to find an optimal solution of your model without compromising on any degrees of freedom. I don't know what you mean by your last sentence. If nothing is explicity provided, the solver tries to seek some start values by the logics and algorithms it has implemented.

simnh commented 3 years ago

That's why I wrote "Without the .fix() call" ;-) . But the rest of the code code be similar, i.e. setting values for the variables but NOT fixing them. I think these values would be passed to the solver and used by gurobi etc. if warmstart argument is also provided. In contrast to the pyomo docs that provide an abtract model which first needs to be created (instance = model.create()) before values to variables can be assigned, we already work on a concrete model instance the whole time. Therefore it should work like we do for the fixed values - without fixing them but still setting them (sounds strange, but that is what we need to do, I think)

jokochems commented 2 years ago

I'll close this for now. We can reopen if needed.

p-snft commented 2 years ago

I totally lost track about this one. Shouldn't it be very easy to implement? All we would need is a name for the parameter that can be given instead of fix. What about expected or hint?

jokochems commented 2 years ago

I closed it lately since nobody had urgent need for that at the dev meeting.

I share your opinion that passing start values shouldn't be too hard and can basically be done by specifying an expected attribute for the components / flows and passing it down to the respective blocks to explicitly set / update the initialize attribute.

Nevertheless, the difficult thing is to find start values in the first place (which basically require a previous model run with similar parameterization and some sort of a feedback, ideally only affecting the pyomo level and not requiring for another model build). But this could potentially be addressed in some future PR.