Add unified time and event scheduling API to Model#3152
Closed
Add unified time and event scheduling API to Model#3152
Conversation
Introduces clean scheduling and run control methods directly on Model, providing a unified interface for both traditional time-step advancement and discrete event simulation. New Model methods: - schedule_at(callback, time): Schedule event at absolute time - schedule_after(callback, delay): Schedule event after delay - cancel_event(event): Cancel a scheduled event - run_until(end_time): Run until specific time - run_for(duration): Run for specific duration - run_while(condition): Run while condition is true - run_next_event(): Execute next scheduled event Implementation: - Creates timeflow.py with Scheduler and RunControl classes - Model delegates to internal _scheduler and _run_control instances - Modifies _wrapped_step to use run_for(1) internally - Non-breaking: existing step-based models work unchanged This lays the foundation for more advanced features like recurring methods and agent self-scheduling while maintaining full backward compatibility.
|
Performance benchmarks:
|
Member
Author
The other approach is that we make |
Member
Author
|
The latter would make for an extremely clean API: Pattern 1: Pure classical ABMclass WolfSheep(Model):
def step(self):
self.agents.shuffle_do("step")
model = WolfSheep()
model.run_for(100) # step() auto-scheduled at t=1,2,3...Pattern 2: Hybridclass WolfSheep(Model):
def __init__(self):
super().__init__()
self.schedule_at(self.drought, time=50)
def step(self):
self.agents.shuffle_do("step")
model = WolfSheep()
model.run_for(100) # step() at t=1,2,3... + drought at t=50Pattern 3: Pure event-driven (no step)class QueueingModel(Model):
def __init__(self):
super().__init__()
# Don't override step(), so it doesn't get auto-scheduled
self.schedule_at(self.customer_arrival, time=0) |
Member
|
I can only comment on the API at the moment; I have no time to review the code at this moment.
|
Member
Author
|
Succeeded by production PR #3155. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR implements the first phase of the unified time and event scheduling API discussed in #2921. It integrates event scheduling directly into the
Modelclass, making it simple to use both traditional time-stepping and discrete event simulation without breaking any existing functionality.Basically, this PR does two things:
Model.step()run the model for 1 timestepMotivation
Currently, users who want to use event scheduling must work with the experimental
Simulatorclasses (ABMSimulator,DEVSimulator), which requires managing two separate objects and understanding the distinction between them. This creates unnecessary complexity for a feature that should be a natural part of Mesa models.This PR makes event scheduling a first-class citizen by integrating it directly into
Model, while maintaining full backward compatibility with existing step-based models.Usage patterns
This API enables classical ABM, pure event-driven, and hybrid stuff in between. I think
1. Pure classical ABM
Everything happens in
step(), time advances in integer increments:This is what most people who don't use a
simulatordo now.2. Hybrid: step + events
Regular stepping with scheduled one-off or agent-triggered events:
This is functionally equivalent to the ABMScheduler, but you still call model.step(). So instead of a scheduler scheduling the step, this works the other way around, the step run the scheduled events (if any).
3. Pure event-driven (no step)
No regular stepping, only scheduled events with continuous time:
This is functionally equivalent to the DEVScheduler.
This PR is fully backward compatible. Users can opt-in to new features without modifying existing code.
Curious what everybody thinks of this approach. Being backwards compatible has a lot going for it, as well as the easy intro into scheduling events.
The only disadvantage might be that users could expect the
run()methods to also perform the step. But I think we can explain that.We could optionally add a
run_steps()utility method:If we agree on this direction, I will add/update tests, the simulator, example models and the tutorial.
Part of #2921.