@@ -4,15 +4,17 @@ $TYPEDSIGNATURES
44Retrieve anticipative routes solution from the given MIP solution `y`.
55Outputs a set of routes per epoch.
66"""
7- function retrieve_routes_anticipative (y:: AbstractArray , dvspenv:: DVSPEnv , customer_index)
7+ function retrieve_routes_anticipative (
8+ y:: AbstractArray , dvspenv:: DVSPEnv , customer_index, epoch_indices
9+ )
810 nb_tasks = length (customer_index)
9- first_epoch = 1
10- (; last_epoch) = dvspenv. instance
11+ # first_epoch = 1
12+ # (; last_epoch) = dvspenv.instance
1113 job_indices = 2 : (nb_tasks)
12- epoch_indices = first_epoch: last_epoch
14+ # epoch_indices = first_epoch:last_epoch
1315
1416 routes = [Vector{Int}[] for _ in epoch_indices]
15- for t in epoch_indices
17+ for (i, t) in enumerate ( epoch_indices)
1618 start = [i for i in job_indices if y[1 , i, t] ≈ 1 ]
1719 for task in start
1820 route = Int[]
@@ -28,7 +30,7 @@ function retrieve_routes_anticipative(y::AbstractArray, dvspenv::DVSPEnv, custom
2830 end
2931 current_task = next_task
3032 end
31- push! (routes[t ], route)
33+ push! (routes[i ], route)
3234 end
3335 end
3436 return routes
@@ -44,28 +46,33 @@ function anticipative_solver(
4446 env:: DVSPEnv ,
4547 scenario= env. scenario;
4648 model_builder= highs_model,
47- reset_env= false ,
48- two_dimensional_features= false ,
49+ two_dimensional_features= env. instance. two_dimensional_features,
50+ reset_env= true ,
51+ nb_epochs= typemax (Int),
4952)
50- reset_env && reset! (env)
53+ reset_env && reset! (env; reset_seed= true )
54+
55+ start_epoch = current_epoch (env)
56+ end_epoch = min (last_epoch (env), start_epoch + nb_epochs - 1 )
57+ T = start_epoch: end_epoch
58+
5159 request_epoch = [0 ]
52- for (epoch, indices) in enumerate (scenario . indices)
53- request_epoch = vcat (request_epoch, fill (epoch , length (indices)))
60+ for t in T
61+ request_epoch = vcat (request_epoch, fill (t , length (scenario . indices[t] )))
5462 end
55- customer_index = vcat (1 , scenario. indices... )
56- service_time = vcat (0.0 , scenario. service_time... )
57- start_time = vcat (0.0 , scenario. start_time... )
63+ customer_index = vcat (1 , scenario. indices[T] . .. )
64+ service_time = vcat (0.0 , scenario. service_time[T] . .. )
65+ start_time = vcat (0.0 , scenario. start_time[T] . .. )
5866
5967 duration = env. instance. static_instance. duration[customer_index, customer_index]
60- first_epoch = 1
61- (; last_epoch, epoch_duration, Δ_dispatch) = env. instance
68+ (; epoch_duration, Δ_dispatch) = env. instance
6269
6370 model = model_builder ()
6471 set_silent (model)
6572
6673 nb_nodes = length (customer_index)
6774 job_indices = 2 : nb_nodes
68- epoch_indices = first_epoch: last_epoch
75+ epoch_indices = T # first_epoch:last_epoch
6976
7077 @variable (model, y[i= 1 : nb_nodes, j= 1 : nb_nodes, t= epoch_indices]; binary= true )
7178
@@ -102,7 +109,7 @@ function anticipative_solver(
102109
103110 # a trip from i can be done only before limit date
104111 for i in job_indices, t in epoch_indices, j in 1 : nb_nodes
105- if (t - 1 ) * epoch_duration + duration[1 , i] + Δ_dispatch > start_time[i] # ! this only works if first_epoch = 1
112+ if (t - 1 ) * epoch_duration + duration[1 , i] + Δ_dispatch > start_time[i]
106113 @constraint (model, y[i, j, t] <= 0 )
107114 end
108115 end
@@ -121,27 +128,32 @@ function anticipative_solver(
121128 optimize! (model)
122129
123130 obj = JuMP. objective_value (model)
124- epoch_routes = retrieve_routes_anticipative (value .(y), env, customer_index)
131+ epoch_routes = retrieve_routes_anticipative (
132+ value .(y), env, customer_index, epoch_indices
133+ )
125134
126135 epoch_indices = Vector{Int}[]
127136 N = 1
128137 indices = [1 ]
129- for epoch in 1 : last_epoch
138+ index = 1
139+ for epoch in 1 : last_epoch (env)
130140 M = length (scenario. indices[epoch])
131141 indices = vcat (indices, (N + 1 ): (N + M))
132142 push! (epoch_indices, copy (indices))
133143 N = N + M
134- epoch_routes[epoch]
135- dispatched = vcat (epoch_routes[epoch]. .. )
136- indices = setdiff (indices, dispatched)
144+ if epoch in T
145+ dispatched = vcat (epoch_routes[index]. .. )
146+ index += 1
147+ indices = setdiff (indices, dispatched)
148+ end
137149 end
138150
139151 indices = vcat (1 , scenario. indices... )
140152 start_time = vcat (0.0 , scenario. start_time... )
141153 service_time = vcat (0.0 , scenario. service_time... )
142154
143- dataset = map (1 : last_epoch) do epoch
144- routes = epoch_routes[epoch ]
155+ dataset = map (enumerate (T)) do (i, epoch)
156+ routes = epoch_routes[i ]
145157 epoch_customers = epoch_indices[epoch]
146158
147159 y_true =
@@ -170,9 +182,13 @@ function anticipative_solver(
170182 epoch_duration = env. instance. epoch_duration
171183 Δ_dispatch = env. instance. Δ_dispatch
172184 planning_start_time = (epoch - 1 ) * epoch_duration + Δ_dispatch
173- is_must_dispatch[2 : end ] .=
174- planning_start_time .+ epoch_duration .+ @view (new_duration[1 , 2 : end ]) .>
175- new_start_time[2 : end ]
185+ if epoch == last_epoch
186+ # If we are in the last epoch, all requests must be dispatched
187+ is_must_dispatch[2 : end ] .= true
188+ else
189+ is_must_dispatch[2 : end ] .=
190+ planning_start_time .+ epoch_duration .+ @view (new_duration[1 , 2 : end ]) .> new_start_time[2 : end ]
191+ end
176192 is_postponable[2 : end ] .= .! is_must_dispatch[2 : end ]
177193
178194 state = DVSPState (;
@@ -183,7 +199,6 @@ function anticipative_solver(
183199 current_epoch= epoch,
184200 )
185201
186- # x = compute_2D_features(state, env.instance)
187202 x = if two_dimensional_features
188203 compute_2D_features (state, env. instance)
189204 else
@@ -195,17 +210,3 @@ function anticipative_solver(
195210
196211 return obj, dataset
197212end
198-
199- # @kwdef struct AnticipativeSolver
200- # is_2D::Bool = false
201- # end
202-
203- # function (solver::AnticipativeSolver)(env::DVSPEnv, scenario=env.scenario; reset_env=false)
204- # return generate_anticipative_decision(
205- # env,
206- # scenario;
207- # model_builder=highs_model,
208- # reset_env,
209- # two_dimensional_features=solver.is_2D,
210- # )
211- # end
0 commit comments