Skip to content

Ability to control the allowed state transitions during a simulation#284

Open
FlxPo wants to merge 23 commits intomainfrom
state-transitions-restrictions
Open

Ability to control the allowed state transitions during a simulation#284
FlxPo wants to merge 23 commits intomainfrom
state-transitions-restrictions

Conversation

@FlxPo
Copy link
Copy Markdown
Contributor

@FlxPo FlxPo commented Mar 18, 2026

Motivation

See: #283

GroupDayTrips previously allowed all plan transitions at every simulation step, with transitions driven only by utility differences. That means all forms of behavioral adjustment happened on the same timescale, even though some changes are much easier than others in reality.

This PR adds an explicit way to stage behavioral adaptation over iterations. It allows us to reproduce simplified adjustment dynamics, for example by allowing mode changes first, then destination changes, then full daily programme changes, while we work toward a more complete transition-cost model (see #196).


Changes

Added a staged behavior-change API to GroupDayTrips parameters:

  • BehaviorChangeScope
    • FULL_REPLANNING
    • DESTINATION_REPLANNING
    • MODE_REPLANNING
  • BehaviorChangePhase(start_iteration, scope)
  • behavior_change_phases
  • get_behavior_change_scope(iteration)

Implemented scope-aware behavior in the GroupDayTrips flow:

  • in DestinationSequences
  • in PlanUpdater

Behavior by scope:

  • FULL_REPLANNING
    • activity, destination, and mode sequences may change
  • DESTINATION_REPLANNING
    • activity sequences are fixed
    • destination and dependent mode sequences may change
  • MODE_REPLANNING
    • activity and destination sequences are fixed
    • only mode sequences may change

Stay-home behavior is defined explicitly:

  • stay-home remains available in FULL_REPLANNING
  • stay-home is frozen in MODE_REPLANNING and DESTINATION_REPLANNING

Architecture changes:

  • behavior-change policy lives in core/parameters.py
  • destination reuse / restricted resampling lives in plans/destination_sequences.py
  • transition legality lives in plans/plan_updater.py
  • aligned the tests with the new architecture from the refactor branch.

Added tests for:

  • phase resolution
  • restricted destination-sequence generation
  • transition legality under restricted scopes
  • integration of phased behavior changes in a real GroupDayTrips run

Example

from mobility.trips.group_day_trips import (
    BehaviorChangePhase,
    BehaviorChangeScope,
    GroupDayTrips,
    Parameters,
)

parameters = Parameters(
    n_iterations=12,
    behavior_change_phases=[
        BehaviorChangePhase(
            start_iteration=1,
            scope=BehaviorChangeScope.FULL_REPLANNING,
        ),
        BehaviorChangePhase(
            start_iteration=5,
            scope=BehaviorChangeScope.MODE_REPLANNING,
        ),
        BehaviorChangePhase(
            start_iteration=8,
            scope=BehaviorChangeScope.DESTINATION_REPLANNING,
        ),
        BehaviorChangePhase(
            start_iteration=11,
            scope=BehaviorChangeScope.FULL_REPLANNING,
        ),
    ],
)

This means:

  • iterations 1-4: full replanning
  • iterations 5-7: mode replanning only, from the active plans at iteration 4
  • iterations 8-10: destination + mode replanning, from the active plans at iteration 7
  • iterations 11-12: full replanning again

If behavior_change_phases is omitted, all iterations use BehaviorChangeScope.FULL_REPLANNING by default.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 18, 2026

Codecov Report

❌ Patch coverage is 85.19260% with 296 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.60%. Comparing base (79769a7) to head (8c0f9ee).

Files with missing lines Patch % Lines
mobility/trips/group_day_trips/core/results.py 43.96% 144 Missing ⚠️
...ips/group_day_trips/plans/destination_sequences.py 86.52% 19 Missing ⚠️
.../carpool/detailed/detailed_carpool_travel_costs.py 33.33% 18 Missing ⚠️
...lity/transport/costs/transport_costs_aggregator.py 85.21% 17 Missing ⚠️
...lity/trips/group_day_trips/core/group_day_trips.py 81.53% 12 Missing ⚠️
...detailed/detailed_carpool_travel_costs_snapshot.py 55.00% 9 Missing ⚠️
...ips/group_day_trips/iterations/iteration_assets.py 92.03% 9 Missing ⚠️
...bility/trips/group_day_trips/plans/plan_updater.py 90.90% 9 Missing ⚠️
...y/transport/modes/public_transport/gtfs_builder.py 93.57% 7 Missing ⚠️
mobility/runtime/parameter_profiles.py 89.28% 6 Missing ⚠️
... and 18 more
Additional details and impacted files
@@             Coverage Diff             @@
##             main     #284       +/-   ##
===========================================
+ Coverage   59.06%   74.60%   +15.53%     
===========================================
  Files         129      146       +17     
  Lines        6738     6406      -332     
===========================================
+ Hits         3980     4779      +799     
+ Misses       2758     1627     -1131     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@FlxPo FlxPo force-pushed the state-transitions-restrictions branch from d0dbe83 to 48cca99 Compare March 30, 2026 22:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant