SpineOpt.jl
SpineOpt.jl copied to clipboard
Use solution from previous Benders iteration to warm start solver
The only thing that will change between Benders iterations are the investment variables... the subproblem solution from the previous benders iteration should at least provide a feasible starting point for the solver in the next iteration
I did something on this in my experimental branch (https://github.com/spine-tools/SpineOpt.jl/commit/27c2ad9b8dc44acf3167c1db5e2927a958136bfa) and it's very effective!
I think that what I have done is not perfect, because it also warm starts the investment variables that are fixed to the new Benders solution, but the solver seems smart enough to fix it
@manuelma could you please look at this... I'm not sure if what I have done means we all have two copies of the saved solution... I think we might not be able to avoid this as we don't save everything in m.ext.values (or do we?).
Also, maybe there is a better way than this to more explicitly omit the investment variables, but maybe this is ok for now: https://github.com/spine-tools/SpineOpt.jl/commit/e5adeb7f4ef883bd0aaf04e184e6af1a37072e86
It works really well, so we should incorporate this into master at least.
Also, I wonder is there a better way at including custom constraints in our models like this without having to create our own branch... or maybe that's ok? The problem is that often, one would need, in addition to the new constraint, new pre-processing or post processing steps, so it could be difficult to find a way to include custom constraints in a more modular way
Amazing stuff @DillonJ - as far as I can see, the amount of extra storage you introduced is optimal. We will have one copy of the solution for each window, plus the rolling copy we had previously. We can't do any better than this I don't think. The only minor optimisation I can see is to not save the solution for the investment variables since we are not warmstarting those. I will add some unit-tests and then make that only change soon.
Thanks @manuelma The investment variables will be a tiny overhead, so not sure it's worth putting too much time into that
It just takes a second and the memory usage of a simple SpineOpt run is pretty high already, so I think it's worth keeping it as tight as possible even if it's a tiny difference as you correctly say.
Fair enough :-)
Actually, what we need to do is use set_start_value()
to set the start value of the investment variables to their fixed value. I am currently doing a run with slightly bigger sub problem windows and warm starting it isn't as effective as before. The solver says it has no solution from the MIP start and tries to repair it - but if it had a fully feasible starting solution, it may be a lot better. Perhaps you can investigate @manuelma
@DillonJ I think the issue might be that occursin()
is being called with the arguments in the wrong order, so it is not skipping the investment variables. As result, we are setting the start value for the invesment variables to the value of the previous iteration, and at the same time fixing them to the value of the current iteration?
I might have fixed it in the latest min-res-gen branch.
Nice... let's see how this works. I suspected something was wrong alright. The more complete soution would be to warmstart the investment variables to their fixed values. I will report back here when I see how it goes
So I'm running with the latest version and get this:
Warning: Non-integral bounds for integer variables rounded.
Warning: No solution found from 1 MIP starts.
Retaining values of one MIP start for possible repair.
Warning: Non-integral bounds for integer variables rounded.
I can't see why the solution from the previous Benders iteration for the same window wouldn't be a solution for the next iteration... maybe you can test on a small system @manuelma
Maybe the rounding issue is related? Maybe it's just small differences. I think the warm start still helps, but perhaps could be improved further
@DillonJ Looks like you've made some progress on this - has it already been merged?