From 82d31dfbb75eae5967632341bf37880aa8c3a451 Mon Sep 17 00:00:00 2001 From: BatyLeo Date: Wed, 9 Apr 2025 14:30:57 +0200 Subject: [PATCH 1/5] Implement the deterministic vsp as a possible solver --- .../StochasticVehicleScheduling.jl | 4 +- .../solution/algorithms/deterministic_mip.jl | 45 +++++++++++++++++++ test/vsp.jl | 9 +++- 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 src/StochasticVehicleScheduling/solution/algorithms/deterministic_mip.jl diff --git a/src/StochasticVehicleScheduling/StochasticVehicleScheduling.jl b/src/StochasticVehicleScheduling/StochasticVehicleScheduling.jl index d6d2558..150f147 100644 --- a/src/StochasticVehicleScheduling/StochasticVehicleScheduling.jl +++ b/src/StochasticVehicleScheduling/StochasticVehicleScheduling.jl @@ -3,7 +3,8 @@ module StochasticVehicleScheduling export StochasticVehicleSchedulingBenchmark export generate_dataset, generate_maximizer, generate_statistical_model export plot_instance, plot_solution -export compact_linearized_mip, compact_mip, column_generation_algorithm, local_search +export compact_linearized_mip, + compact_mip, column_generation_algorithm, local_search, deterministic_mip export evaluate_solution, is_feasible using ..Utils @@ -44,6 +45,7 @@ include("solution/solution.jl") include("solution/algorithms/mip.jl") include("solution/algorithms/column_generation.jl") include("solution/algorithms/local_search.jl") +include("solution/algorithms/deterministic_mip.jl") include("maximizer.jl") diff --git a/src/StochasticVehicleScheduling/solution/algorithms/deterministic_mip.jl b/src/StochasticVehicleScheduling/solution/algorithms/deterministic_mip.jl new file mode 100644 index 0000000..5f68190 --- /dev/null +++ b/src/StochasticVehicleScheduling/solution/algorithms/deterministic_mip.jl @@ -0,0 +1,45 @@ +""" +$TYPEDSIGNATURES + +Solves the deterministic version of the vehicle scheduling problem using a MIP model. +Does not take into account the stochastic nature of the problem. +""" +function deterministic_mip(instance::Instance; model_builder=highs_model, silent=true) + (; graph, vehicle_cost) = instance + nb_nodes = nv(graph) + job_indices = 2:(nb_nodes - 1) + nodes = 1:nb_nodes + + # Model definition + model = model_builder() + silent && set_silent(model) + + # Variables and objective function + @variable(model, y[u in nodes, v in nodes; has_edge(graph, u, v)], Bin) + + @objective( + model, + Min, + vehicle_cost * sum(y[1, v] for v in job_indices) # nb_vehicles + ) + + # Flow contraints + @constraint( + model, + flow[i in job_indices], + sum(y[j, i] for j in inneighbors(graph, i)) == + sum(y[i, j] for j in outneighbors(graph, i)) + ) + @constraint( + model, + unit_demand[i in job_indices], + sum(y[j, i] for j in inneighbors(graph, i)) == 1 + ) + + # Solve model + optimize!(model) + solution = value.(y) + + sol = solution_from_JuMP_array(solution, graph) + return sol +end diff --git a/test/vsp.jl b/test/vsp.jl index 595b38c..03c703a 100644 --- a/test/vsp.jl +++ b/test/vsp.jl @@ -11,6 +11,7 @@ mip_dataset = generate_dataset(b, N; seed=0, algorithm=compact_mip) mipl_dataset = generate_dataset(b, N; seed=0, algorithm=compact_linearized_mip) local_search_dataset = generate_dataset(b, N; seed=0, algorithm=local_search) + deterministic_dataset = generate_dataset(b, N; seed=0, algorithm=deterministic_mip) @test length(dataset) == N figure_1 = plot_instance(b, dataset[1]) @@ -25,11 +26,17 @@ gap_mip = compute_gap(b, mip_dataset, model, maximizer) gap_mipl = compute_gap(b, mipl_dataset, model, maximizer) gap_local_search = compute_gap(b, local_search_dataset, model, maximizer) + gap_deterministic = compute_gap(b, deterministic_dataset, model, maximizer) - @test gap >= 0 && gap_mip >= 0 && gap_mipl >= 0 && gap_local_search >= 0 + @test gap >= 0 && + gap_mip >= 0 && + gap_mipl >= 0 && + gap_local_search >= 0 && + gap_deterministic >= 0 @test gap_mip ≈ gap_mipl rtol = 1e-2 @test gap_mip >= gap_local_search @test gap_mip >= gap + @test gap__local_search >= gap_deterministic for sample in dataset x = sample.x From b005c02ff73a0b2a348aade7783624fbc462fa8a Mon Sep 17 00:00:00 2001 From: BatyLeo Date: Wed, 9 Apr 2025 14:32:22 +0200 Subject: [PATCH 2/5] bump version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index f2bc82e..d9500c6 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "DecisionFocusedLearningBenchmarks" uuid = "2fbe496a-299b-4c81-bab5-c44dfc55cf20" authors = ["Members of JuliaDecisionFocusedLearning"] -version = "0.2.1" +version = "0.2.2" [deps] ConstrainedShortestPaths = "b3798467-87dc-4d99-943d-35a1bd39e395" From d6e42aeadaced6501cf99b533e1ba2a948adfaf3 Mon Sep 17 00:00:00 2001 From: BatyLeo Date: Wed, 9 Apr 2025 14:32:43 +0200 Subject: [PATCH 3/5] fix --- test/vsp.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/vsp.jl b/test/vsp.jl index 03c703a..9003bb1 100644 --- a/test/vsp.jl +++ b/test/vsp.jl @@ -36,7 +36,7 @@ @test gap_mip ≈ gap_mipl rtol = 1e-2 @test gap_mip >= gap_local_search @test gap_mip >= gap - @test gap__local_search >= gap_deterministic + @test gap_local_search >= gap_deterministic for sample in dataset x = sample.x From 6eae25f45ec4112661bb2c9caa6065c7293be620 Mon Sep 17 00:00:00 2001 From: BatyLeo Date: Wed, 9 Apr 2025 14:59:23 +0200 Subject: [PATCH 4/5] fix tests --- test/vsp.jl | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test/vsp.jl b/test/vsp.jl index 9003bb1..bb78282 100644 --- a/test/vsp.jl +++ b/test/vsp.jl @@ -28,11 +28,7 @@ gap_local_search = compute_gap(b, local_search_dataset, model, maximizer) gap_deterministic = compute_gap(b, deterministic_dataset, model, maximizer) - @test gap >= 0 && - gap_mip >= 0 && - gap_mipl >= 0 && - gap_local_search >= 0 && - gap_deterministic >= 0 + @test gap >= 0 && gap_mip >= 0 && gap_mipl >= 0 && gap_local_search >= 0 @test gap_mip ≈ gap_mipl rtol = 1e-2 @test gap_mip >= gap_local_search @test gap_mip >= gap From 25e9ac8122742e13e71fe376d889645e56156b74 Mon Sep 17 00:00:00 2001 From: BatyLeo Date: Wed, 9 Apr 2025 15:30:53 +0200 Subject: [PATCH 5/5] use StableRNG --- test/vsp.jl | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/test/vsp.jl b/test/vsp.jl index bb78282..1c3b5fd 100644 --- a/test/vsp.jl +++ b/test/vsp.jl @@ -3,15 +3,22 @@ using DecisionFocusedLearningBenchmarks.StochasticVehicleScheduling using Graphs using Plots + using StableRNGs: StableRNG b = StochasticVehicleSchedulingBenchmark(; nb_tasks=25, nb_scenarios=10) N = 5 - dataset = generate_dataset(b, N; seed=0) - mip_dataset = generate_dataset(b, N; seed=0, algorithm=compact_mip) - mipl_dataset = generate_dataset(b, N; seed=0, algorithm=compact_linearized_mip) - local_search_dataset = generate_dataset(b, N; seed=0, algorithm=local_search) - deterministic_dataset = generate_dataset(b, N; seed=0, algorithm=deterministic_mip) + dataset = generate_dataset(b, N; seed=0, rng=StableRNG(0)) + mip_dataset = generate_dataset(b, N; seed=0, rng=StableRNG(0), algorithm=compact_mip) + mipl_dataset = generate_dataset( + b, N; seed=0, rng=StableRNG(0), algorithm=compact_linearized_mip + ) + local_search_dataset = generate_dataset( + b, N; seed=0, rng=StableRNG(0), algorithm=local_search + ) + deterministic_dataset = generate_dataset( + b, N; seed=0, rng=StableRNG(0), algorithm=deterministic_mip + ) @test length(dataset) == N figure_1 = plot_instance(b, dataset[1]) @@ -28,7 +35,6 @@ gap_local_search = compute_gap(b, local_search_dataset, model, maximizer) gap_deterministic = compute_gap(b, deterministic_dataset, model, maximizer) - @test gap >= 0 && gap_mip >= 0 && gap_mipl >= 0 && gap_local_search >= 0 @test gap_mip ≈ gap_mipl rtol = 1e-2 @test gap_mip >= gap_local_search @test gap_mip >= gap