Skip to content

feat!: Implement AbstractPolicy type hierarchy - #108

Merged
BatyLeo merged 7 commits into
mainfrom
issue_106_improve_policies
Aug 6, 2026
Merged

feat!: Implement AbstractPolicy type hierarchy#108
BatyLeo merged 7 commits into
mainfrom
issue_106_improve_policies

Conversation

@NicolasCorvol

@NicolasCorvol NicolasCorvol commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

This pull request addresses the issues raised in: #93 and #106

This PR introduces a new policy hierarchy based on an abstract AbstractPolicy type with two subtypes:

  • AbstractRolloutPolicy: policies that produce a decision from the current state at each step of a rollout.
  • AbstractFullHorizonPolicy: policies that, given an initial state and a planning horizon, compute the complete sequence of decisions in advance. This is particularly useful for anticipative or offline planning policies.

Benefits:

  • More flexible rollouts. Each benchmark can now implement its own single_rollout! method, allowing users to choose which fields should be recorded in the resulting DataSample.
  • Cleaner sample and dataset generation. For stochastic benchmarks, the function generate_sample currently has an unstable interface because it requires a target_policy that can be nothing while otherwise being expected to be callable with specific arguments. The new policy types makes it possible to refactor this API into a cleaner and more type-stable design.

Notes: To keep this PR focused and make the changes incremental, the existing Policy struct has been left unchanged. It could be revisited.

@NicolasCorvol
NicolasCorvol requested a review from BatyLeo July 22, 2026 09:27
@NicolasCorvol NicolasCorvol self-assigned this Jul 22, 2026
@NicolasCorvol NicolasCorvol added the enhancement New feature or request label Jul 22, 2026
@BatyLeo BatyLeo changed the title Add AbstractPolicy type feat!: Implement AbstractPolicy type hierarchy Jul 22, 2026

@BatyLeo BatyLeo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice PR, I just have a few minor comments and suggestions, otherwise it's great!

Comment thread src/Utils/policy.jl
Comment thread src/Utils/policy.jl Outdated
callable in `Policy{B}` makes it an [`AbstractRolloutPolicy`](@ref)`{B}`, which enables
per-benchmark specialization of [`single_rollout!`](@ref).
"""
struct Policy{B,P} <: AbstractRolloutPolicy{B}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: This is not necessarily a dynamic policy, we then may need two different policy wrappers, once for stochastic policies, and one for dynamic ones (there are no static policies for now in the benchmarks).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completely agree, and I was thinking about that while coding the PR.
Should we make a following PR that implements policies for static benchmarks ?
This would unify everything and make it easier for metrics too (see #109)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created a ScenarioPolicy and kept the Policy structure for dynamic benchmarks in b0d8396, should we update the naming of Policy too ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's fine, at some point we may want to get rid of these Policy and ScenarioPolicy wrappers, which are not very useful in practice

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logged in #119

Comment thread src/Utils/policy.jl
Comment thread src/Utils/policy.jl
Comment thread src/Utils/policy.jl
Comment thread src/Utils/policy.jl Outdated
features, state = observe(env)
state_copy = deepcopy(state)
reward = step!(env, y, rng)
return DataSample(; x=features, y=y, instance=state_copy, extra=(; reward))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Do we want to keep the instance field name for now and rename it to state in a future PR?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, I think we can keep it and address it in a following PR.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logged in #119

Comment thread src/Utils/policy.jl Outdated
Comment thread src/Utils/Utils.jl Outdated
Comment thread src/DynamicVehicleScheduling/policy.jl Outdated
@codecov

codecov Bot commented Jul 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.66667% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/Utils/policy.jl 86.66% 2 Missing ⚠️
Files with missing lines Coverage Δ
...tualStochasticArgmax/ContextualStochasticArgmax.jl 94.28% <100.00%> (ø)
src/DecisionFocusedLearningBenchmarks.jl 100.00% <ø> (ø)
src/DynamicAssortment/DynamicAssortment.jl 100.00% <100.00%> (ø)
...namicVehicleScheduling/DynamicVehicleScheduling.jl 100.00% <100.00%> (ø)
src/DynamicVehicleScheduling/policy.jl 75.00% <100.00%> (+3.57%) ⬆️
src/Maintenance/Maintenance.jl 100.00% <100.00%> (ø)
src/StochasticVehicleScheduling/policies.jl 81.25% <ø> (ø)
src/Utils/Utils.jl 100.00% <ø> (ø)
src/Utils/policy.jl 90.19% <86.66%> (-3.14%) ⬇️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread src/Utils/policy.jl Outdated

@BatyLeo BatyLeo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are some last few comments.

In addition to the comments below, now that we have defined the AbstractDynamicPolicy alias, we use it to type evaluate_policy! policy arg:

function evaluate_policy!(policy::DynamicPolicy

After these few comments, I think we're good.

Comment thread src/Utils/Utils.jl Outdated
Comment thread src/Utils/policy.jl Outdated
Comment thread src/Utils/policy.jl Outdated
Comment thread src/Utils/policy.jl
Comment thread src/Utils/policy.jl Outdated
Comment thread src/Utils/policy.jl Outdated
return nothing
end
"""
"""scen

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes :(

@BatyLeo BatyLeo mentioned this pull request Aug 4, 2026
@BatyLeo
BatyLeo merged commit 1e2a027 into main Aug 6, 2026
4 checks passed
@BatyLeo
BatyLeo deleted the issue_106_improve_policies branch August 6, 2026 09:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants