Rolling Horizon Implementation

I have an optimization problem with a long time period (96 steps). Reading some papers [1][2], it seems a common way to reduce the optimization time of a Mixed Integer Linear Programming problem is to use something called Rolling Horizon, which is synonymous to Receding Horizon Control and Model Predictive Control.

I’m new to mathematical optimization and JuliaOpt, but I was wondering if there were any examples using this approach to solve an optimization problem?

[1] “Reducing Computation Time with a Rolling Horizon Approach Applied to a MILP Formulation of Multiple Urban Energy Hub System” by Marquant et al.
[2] “Optimization of a network of compressors in parallel: Operational and maintenance planning – The air separation plant case” by Kopanos et al.

Typically this is just a roll-your-own type model. You would typically do something like

function solve_stage_t(incoming_state)
    model = Model()
    # ... definition using `incoming_state`
    optimize!(model)
    return outgoing_state
end

state = [initial_state]
for t in 1:T
    push!(state, solve_stage_t(state[end]))
end 

If rebuilding the model every step is a bottleneck (don’t assume this! Try solving the problem first and then time it.), you might want to look at GitHub - tkoolen/Parametron.jl: Efficiently solving instances of a parameterized family of (possibly mixed-integer) linear/quadratic optimization problems in Julia or https://github.com/JuliaStochOpt/ParameterJuMP.jl/.

2 Likes

Hi! What was the final implementation for this?
Cause I’m having a similar issue depending on the solver I use.
Here’s the draft of my MWE:

include(makeModels.jl) # <-- I create the spvModel
function rollingHorizon(EMSdata,
    W, # weights
    Tw, # time window [days]
    steps, # number of steps to move the window
    Δt) # time length of each step [hr]
    # Initialize
    tend = 24*Tw; # [hr]
    Dt=0:Δt:tend; Dt=Dt*3600; # time array in seconds
    s=modelSettings(nEV=1:2, dTime=collect(Dt));
    results=Vector{Dict}(undef, steps); # allocate memory
    for ts in 1:steps
        # build+solve model
        model=solvePolicies(KNITRO.Optimizer, s, data); 
        results[ts]=getResults(model);
        # update data
        data=update_data(results[ts], s, data);
        # move time window
        Dt = Dt .+ Δt*3600.0;
        s.dTime=collect(Dt);
    end
    return results
end

Doing this with Ipopt worked and with KNITRO didn’t. Even if I do model=InfiniteModel(); in the middle.