Skip to content

Commit 38923a2

Browse files
committed
Add the option to compute solutions on generate dataset
1 parent 357f31c commit 38923a2

File tree

4 files changed

+41
-40
lines changed

4 files changed

+41
-40
lines changed

src/StochasticVehicleScheduling/StochasticVehicleScheduling.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,34 @@ end
6666
$TYPEDSIGNATURES
6767
6868
Create a dataset of `dataset_size` instances for the given `StochasticVehicleSchedulingBenchmark`.
69+
If you want to also add label solutions in the dataset, set `compute_solutions=true`.
70+
By default, they will be computed using column generation.
71+
Note that computing solutions can be time-consuming, especially for large instances.
72+
You can also use instead `compact_mip` or `compact_linearized_mip` as the algorithm to compute solutions.
73+
If you want to provide a custom algorithm to compute solutions, you can pass it as the `algorithm` keyword argument.
74+
If `algorithm` takes keyword arguments, you can pass them as well directly in `kwargs...`.
6975
"""
7076
function Utils.generate_dataset(
7177
benchmark::StochasticVehicleSchedulingBenchmark,
7278
dataset_size::Int;
79+
compute_solutions=false,
7380
seed=nothing,
7481
rng=MersenneTwister(0),
82+
algorithm=column_generation_algorithm,
83+
kwargs...,
7584
)
7685
(; nb_tasks, nb_scenarios) = benchmark
7786
Random.seed!(rng, seed)
7887
instances = [Instance(; nb_tasks, nb_scenarios, rng=rng) for _ in 1:dataset_size]
7988
features = get_features.(instances)
89+
if compute_solutions
90+
solutions = [algorithm(instance; kwargs...) for instance in instances]
91+
return [
92+
DataSample(; x=feature, instance, y=solution) for
93+
(instance, feature, solution) in zip(instances, features, solutions)
94+
]
95+
end
96+
# else
8097
return [
8198
DataSample(; x=feature, instance) for
8299
(instance, feature) in zip(instances, features)

src/StochasticVehicleScheduling/solution/exact_algorithms/column_generation.jl

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -89,35 +89,8 @@ function column_generation(
8989
end
9090

9191
c_low = objective_value(model)
92-
paths = cat(initial_paths, new_paths; dims=1)
93-
c_upp, y, _ = compute_solution_from_selected_columns(instance, paths)
94-
95-
# If relaxation requested or solution is optimal, return
96-
# if c_upp ≈ c_low || only_relaxation
97-
# return value.(λ),
98-
# objective_value(model), cat(initial_paths, new_paths; dims=1), dual.(con),
99-
# dual.(cons)
100-
# end
101-
102-
# @info "hello"
103-
# # else, try to close the gap
104-
# threshold = (c_upp - c_low - vehicle_cost) / delay_cost
105-
# λ_val = value.(λ)
106-
# @info "" size(intrinsic_delays) threshold
107-
# additional_paths, costs = stochastic_routing_shortest_path_with_threshold(
108-
# graph,
109-
# slacks,
110-
# intrinsic_delays,
111-
# λ_val ./ delay_cost;
112-
# threshold,
113-
# bounding,
114-
# use_convex_resources,
115-
# )
116-
# @info "done"
117-
118-
return value.(λ),
119-
objective_value(model), unique(cat(initial_paths, new_paths; dims=1)), dual.(con),
120-
dual.(cons)
92+
columns = unique(cat(initial_paths, new_paths; dims=1))
93+
return columns
12194
end
12295

12396
"""
@@ -171,15 +144,20 @@ function compute_solution_from_selected_columns(
171144
return objective_value(model), sol, paths[isapprox.([sol[p] for p in paths], 1.0)]
172145
end
173146

147+
"""
148+
$TYPEDSIGNATURES
149+
150+
Solve input instance using column generation.
151+
"""
174152
function column_generation_algorithm(
175-
instance::Instance,
176-
scenario_range=nothing;
177-
bounding=false,
178-
use_convex_resources=false,
153+
instance::Instance;
154+
scenario_range=nothing,
155+
bounding=true,
156+
use_convex_resources=true,
179157
silent=true,
180158
)
181159
Ω = isnothing(scenario_range) ? (1:get_nb_scenarios(instance)) : scenario_range
182-
_, _, columns, _, _ = column_generation(
160+
columns = column_generation(
183161
instance;
184162
bounding=bounding,
185163
use_convex_resources=use_convex_resources,

src/StochasticVehicleScheduling/solution/exact_algorithms/mip.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Quadratic constraints are linearized using Mc Cormick linearization.
66
Note: If you have Gurobi, use `grb_model` as `model_builder` instead of `highs_model`.
77
"""
88
function compact_linearized_mip(
9-
instance::Instance, scenario_range=nothing; model_builder=scip_model, silent=true
9+
instance::Instance; scenario_range=nothing, model_builder=scip_model, silent=true
1010
)
1111
(; graph, slacks, intrinsic_delays, vehicle_cost, delay_cost) = instance
1212
nb_nodes = nv(graph)
@@ -78,7 +78,7 @@ function compact_linearized_mip(
7878
solution = value.(y)
7979

8080
sol = solution_from_JuMP_array(solution, graph)
81-
return objective_value(model), sol
81+
return sol
8282
end
8383

8484
"""
@@ -91,7 +91,7 @@ Note: If you have Gurobi, use `grb_model` as `model_builder` instead of `highs_m
9191
You need to use a solver that supports quadratic constraints to use this method.
9292
"""
9393
function compact_mip(
94-
instance::Instance, scenario_range=nothing; model_builder=scip_model, silent=true
94+
instance::Instance; scenario_range=nothing, model_builder=scip_model, silent=true
9595
)
9696
(; graph, slacks, intrinsic_delays, vehicle_cost, delay_cost) = instance
9797
nb_nodes = nv(graph)
@@ -149,5 +149,5 @@ function compact_mip(
149149
solution = value.(y)
150150

151151
sol = solution_from_JuMP_array(solution, graph)
152-
return objective_value(model), sol
152+
return sol
153153
end

test/vsp.jl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,14 @@
55

66
b = StochasticVehicleSchedulingBenchmark(; nb_tasks=25, nb_scenarios=10)
77

8-
N = 50
9-
dataset = generate_dataset(b, N)
8+
N = 10
9+
dataset = generate_dataset(b, N; compute_solutions=true, seed=0)
10+
mip_dataset = generate_dataset(
11+
b, N; compute_solutions=true, seed=0, algorithm=compact_mip
12+
)
13+
mipl_dataset = generate_dataset(
14+
b, N; compute_solutions=true, seed=0, algorithm=compact_linearized_mip
15+
)
1016
@test length(dataset) == N
1117

1218
maximizer = generate_maximizer(b)

0 commit comments

Comments
 (0)