From dd2e64e2e8a7c288ea4d4347b22a7923334858a2 Mon Sep 17 00:00:00 2001 From: BatyLeo Date: Mon, 16 Mar 2026 17:54:57 +0100 Subject: [PATCH 1/2] Create alisases for exogenous/endogenous stochastic/dynamic benchmarks --- src/DecisionFocusedLearningBenchmarks.jl | 2 ++ src/Utils/Utils.jl | 2 ++ src/Utils/interface.jl | 28 +++++++++++++++++------- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/DecisionFocusedLearningBenchmarks.jl b/src/DecisionFocusedLearningBenchmarks.jl index dd6cb94..428346c 100644 --- a/src/DecisionFocusedLearningBenchmarks.jl +++ b/src/DecisionFocusedLearningBenchmarks.jl @@ -63,6 +63,8 @@ using .Utils # Interface export AbstractBenchmark, AbstractStochasticBenchmark, AbstractDynamicBenchmark, DataSample +export ExogenousStochasticBenchmark, + EndogenousStochasticBenchmark, ExogenousDynamicBenchmark, EndogenousDynamicBenchmark export AbstractEnvironment, get_seed, is_terminated, observe, reset!, step! export Policy, evaluate_policy! diff --git a/src/Utils/Utils.jl b/src/Utils/Utils.jl index ae766b1..76d66a0 100644 --- a/src/Utils/Utils.jl +++ b/src/Utils/Utils.jl @@ -27,6 +27,8 @@ export TopKMaximizer export AbstractEnvironment, get_seed, is_terminated, observe, reset!, step! export AbstractBenchmark, AbstractStochasticBenchmark, AbstractDynamicBenchmark +export ExogenousStochasticBenchmark, + EndogenousStochasticBenchmark, ExogenousDynamicBenchmark, EndogenousDynamicBenchmark export generate_instance, generate_sample, generate_dataset export generate_statistical_model, generate_maximizer export generate_scenario diff --git a/src/Utils/interface.jl b/src/Utils/interface.jl index 8d14e31..9922e4d 100644 --- a/src/Utils/interface.jl +++ b/src/Utils/interface.jl @@ -215,7 +215,7 @@ context known before the scenario is revealed) and a **random scenario** (the un part). Decisions are taken by seeing only the instance. Scenarios are used to generate anticipative targets and compute objective values. -# Required methods (exogenous benchmarks, `{true}` only) +# Required methods ([ExogenousStochasticBenchmark](@ref) only) - [`generate_instance`](@ref)`(bench, rng)`: returns a [`DataSample`](@ref) with instance and features but **no scenario**. Scenarios are added later by [`generate_dataset`](@ref) via [`generate_scenario`](@ref). @@ -230,7 +230,7 @@ anticipative targets and compute objective values. `argmin_{y ∈ Y} c(y, scenario) + θᵀy`. # Dataset generation (exogenous only) -[`generate_dataset`](@ref) is specialised for `AbstractStochasticBenchmark{true}` and +[`generate_dataset`](@ref) is specialised for [ExogenousStochasticBenchmark](@ref) and supports all three standard structures via `nb_scenarios`: | Setting | Call | @@ -251,8 +251,14 @@ abstract type AbstractStochasticBenchmark{exogenous} <: AbstractBenchmark end is_exogenous(::AbstractStochasticBenchmark{exogenous}) where {exogenous} = exogenous is_endogenous(::AbstractStochasticBenchmark{exogenous}) where {exogenous} = !exogenous +"Alias for [`AbstractStochasticBenchmark`](@ref)`{true}`. Uncertainty is independent of decisions." +const ExogenousStochasticBenchmark = AbstractStochasticBenchmark{true} + +"Alias for [`AbstractStochasticBenchmark`](@ref)`{false}`. Uncertainty depends on decisions." +const EndogenousStochasticBenchmark = AbstractStochasticBenchmark{false} + """ - generate_scenario(::AbstractStochasticBenchmark{true}, rng::AbstractRNG; kwargs...) -> scenario + generate_scenario(::ExogenousStochasticBenchmark, rng::AbstractRNG; kwargs...) -> scenario Draw a random scenario. Instance and context fields are passed as keyword arguments, spread from `sample.context`: @@ -275,7 +281,7 @@ Return a callable that computes the anticipative solution. function generate_anticipative_solver end """ - generate_parametric_anticipative_solver(::AbstractStochasticBenchmark{true}) -> callable + generate_parametric_anticipative_solver(::ExogenousStochasticBenchmark) -> callable **Optional.** Return a callable `(θ, scenario; kwargs...) -> y` that solves the parametric anticipative subproblem: @@ -299,7 +305,7 @@ Calls [`generate_instance`](@ref), draws `nb_scenarios` scenarios via (K samples, one per scenario) or SAA (1 sample aggregating all K scenarios). """ function generate_sample( - bench::AbstractStochasticBenchmark{true}, + bench::ExogenousStochasticBenchmark, rng; target_policy=nothing, nb_scenarios::Int=1, @@ -337,7 +343,7 @@ scenario draws. The scenario→sample mapping is controlled by the `target_polic - `kwargs...`: forwarded to [`generate_sample`](@ref). """ function generate_dataset( - bench::AbstractStochasticBenchmark{true}, + bench::ExogenousStochasticBenchmark, nb_instances::Int; target_policy=nothing, nb_scenarios::Int=1, @@ -379,6 +385,12 @@ meaning (whether uncertainty is independent of decisions). """ abstract type AbstractDynamicBenchmark{exogenous} <: AbstractStochasticBenchmark{exogenous} end +"Alias for [`AbstractDynamicBenchmark`](@ref)`{true}`. Uncertainty is independent of decisions." +const ExogenousDynamicBenchmark = AbstractDynamicBenchmark{true} + +"Alias for [`AbstractDynamicBenchmark`](@ref)`{false}`. Uncertainty depends on decisions." +const EndogenousDynamicBenchmark = AbstractDynamicBenchmark{false} + """ generate_environment(::AbstractDynamicBenchmark, rng::AbstractRNG; kwargs...) @@ -424,7 +436,7 @@ to obtain standard baseline callables (e.g. the anticipative solver). - `rng`: random number generator. """ function generate_dataset( - bench::AbstractDynamicBenchmark{true}, + bench::ExogenousDynamicBenchmark, environments::AbstractVector; target_policy, seed=nothing, @@ -450,7 +462,7 @@ via [`generate_environments`](@ref), then calls `target_policy` is a **required** keyword argument. """ function generate_dataset( - bench::AbstractDynamicBenchmark{true}, n::Int; target_policy, seed=nothing, kwargs... + bench::ExogenousDynamicBenchmark, n::Int; target_policy, seed=nothing, kwargs... ) environments = generate_environments(bench, n; seed) return generate_dataset(bench, environments; target_policy, seed, kwargs...) From 68e5cdb777108e589d9795d5becef3bb1887aece Mon Sep 17 00:00:00 2001 From: BatyLeo Date: Tue, 17 Mar 2026 09:46:15 +0100 Subject: [PATCH 2/2] cleanup --- src/Utils/interface.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Utils/interface.jl b/src/Utils/interface.jl index 9922e4d..5f42e98 100644 --- a/src/Utils/interface.jl +++ b/src/Utils/interface.jl @@ -215,7 +215,7 @@ context known before the scenario is revealed) and a **random scenario** (the un part). Decisions are taken by seeing only the instance. Scenarios are used to generate anticipative targets and compute objective values. -# Required methods ([ExogenousStochasticBenchmark](@ref) only) +# Required methods ([`ExogenousStochasticBenchmark`](@ref) only) - [`generate_instance`](@ref)`(bench, rng)`: returns a [`DataSample`](@ref) with instance and features but **no scenario**. Scenarios are added later by [`generate_dataset`](@ref) via [`generate_scenario`](@ref). @@ -230,7 +230,7 @@ anticipative targets and compute objective values. `argmin_{y ∈ Y} c(y, scenario) + θᵀy`. # Dataset generation (exogenous only) -[`generate_dataset`](@ref) is specialised for [ExogenousStochasticBenchmark](@ref) and +[`generate_dataset`](@ref) is specialised for [`ExogenousStochasticBenchmark`](@ref) and supports all three standard structures via `nb_scenarios`: | Setting | Call |