Scheduling
Scheduling controls the order in which agents act.
Activation order is a modelling assumption. In agent-based modelling, changing the scheduler can change the simulation result. ABMForge therefore treats schedulers as explicit model components.
Built-in schedulers
| Scheduler | Activation order | Uses model RNG | Skips dead agents | Typical use |
|---|---|---|---|---|
SequentialActivation |
Insertion order | no | yes | deterministic models |
RandomActivation |
Random permutation | yes | yes | stochastic activation assumptions |
SimultaneousActivation |
all step(), then all advance() |
no | yes | cellular automata and synchronous update models |
StagedActivation |
declared stage order | optional | yes | multi-phase agent behaviour |
All built-in schedulers operate on a snapshot of agents selected at the beginning of the scheduler step. Agents created during a scheduler pass are not activated until a later pass.
SequentialActivation
Activates agents in insertion order.
from abmforge.scheduling import SequentialActivation
self.scheduler = SequentialActivation(self)
Use this when deterministic ordering is part of the model design or when you want a simple teaching example.
RandomActivation
Activates living agents in a deterministic random order using the model-level random number generator.
from abmforge.scheduling import RandomActivation
self.scheduler = RandomActivation(self)
Use this when random activation is part of the model assumption.
Given the same model state and seed, RandomActivation should produce reproducible activation order.
SimultaneousActivation
Calls step() for all living agents, then calls advance() for living agents that define it.
from abmforge.scheduling import SimultaneousActivation
self.scheduler = SimultaneousActivation(self)
This is useful when agents should calculate their next state without immediately changing the state observed by other agents.
A typical agent pattern is:
class Cell(Agent):
def step(self):
self.next_state = compute_next_state(self)
def advance(self):
self.state = self.next_state
StagedActivation
Calls named methods on agents in a specified order.
from abmforge.scheduling import StagedActivation
self.scheduler = StagedActivation(
self,
stages=["sense", "decide", "act"],
shuffle=False,
)
If shuffle=True, the model-level RNG is used to shuffle agents within each stage.
Choosing a scheduler
| Modelling need | Recommended scheduler |
|---|---|
| fixed deterministic order | SequentialActivation |
| random order each step | RandomActivation |
| synchronous update | SimultaneousActivation |
| multi-phase agent behaviour | StagedActivation |
Reproducibility notes
For reproducible ABM experiments:
- set the model seed,
- document the scheduler used,
- document whether activation order is deterministic or random,
- avoid relying on accidental dictionary ordering beyond documented insertion-order behaviour,
- include the scheduler choice in scenario or model documentation.
Common pitfalls
Activation order affects results
Two models with the same rules but different schedulers may produce different results.
Newly spawned agents
Built-in schedulers do not activate agents spawned during the same scheduler pass.
Dead agents
Built-in schedulers skip agents with is_alive == False.
Simultaneous update
With SimultaneousActivation, state changes should usually be committed in advance(), not directly in step().
Staged scheduler contract
StagedActivation validates its stage list at construction time. The stage list
must be a non-empty sequence of non-empty strings. Passing a single string is
rejected because it would otherwise be interpreted as a sequence of characters.
Each living agent must provide a callable method for each declared stage. If a
stage method is missing or non-callable, ABMForge raises an AttributeError
that names the agent type, agent id, and missing stage.
Models may define optional hooks:
def before_stage(self, stage: str) -> None:
...
def after_stage(self, stage: str) -> None:
...
These hooks are called before and after each declared stage. They are useful for recording stage-level diagnostics, enforcing invariants, or teaching multi-phase scheduler semantics. Hooks must be callable when defined.
The scheduler still operates on a snapshot of living agents selected at the beginning of the scheduler step. Agents spawned during a staged scheduler pass are not activated until a later pass.
Scheduler metadata
Schedulers expose to_metadata() for JSON-serializable audit metadata. The base
scheduler metadata uses schema version scheduler-metadata-v1 and includes:
schema_version;scheduler_type;module;attached.
StagedActivation.to_metadata() also records:
stages;shuffle.
This metadata is intended for inspection and snapshot audit trails. It is not a scheduler restore contract.