pub struct PoissonSource { /* private fields */ }Expand description
Poisson-arrival traffic generator with time-varying patterns.
Uses an exponential inter-arrival time model: each tick, the generator
checks whether enough time has elapsed since the last spawn. The mean
interval comes from
PassengerSpawnConfig::mean_interval_ticks.
Origin/destination pairs are sampled from a TrafficSchedule that
selects the active TrafficPattern based on the current tick.
§Example
use elevator_core::traffic::PoissonSource;
// From a SimConfig (reads stops and spawn parameters).
let mut source = PoissonSource::from_config(&config);
// Or build manually.
let mut source = PoissonSource::new(
stops,
TrafficSchedule::office_day(3600),
120, // mean_interval_ticks
(60.0, 90.0), // weight_range
);Implementations§
Source§impl PoissonSource
impl PoissonSource
Sourcepub fn new(
stops: Vec<StopId>,
schedule: TrafficSchedule,
mean_interval_ticks: u32,
weight_range: (f64, f64),
) -> Self
pub fn new( stops: Vec<StopId>, schedule: TrafficSchedule, mean_interval_ticks: u32, weight_range: (f64, f64), ) -> Self
Create a new Poisson traffic source.
stops should be sorted by position (lowest first) to match
TrafficPattern expectations (first stop = lobby).
If weight_range.0 > weight_range.1, the values are swapped.
Sourcepub fn from_config(config: &SimConfig) -> Self
pub fn from_config(config: &SimConfig) -> Self
Create a Poisson source from a SimConfig.
Reads stop IDs from the building config and spawn parameters from
passenger_spawning. Uses a constant TrafficPattern::Uniform schedule
by default — call with_schedule to override.
Sourcepub fn with_schedule(self, schedule: TrafficSchedule) -> Self
pub fn with_schedule(self, schedule: TrafficSchedule) -> Self
Replace the traffic schedule.
Sourcepub fn with_mean_interval(self, ticks: u32) -> Self
pub fn with_mean_interval(self, ticks: u32) -> Self
Replace the mean arrival interval and resample the next arrival.
The first scheduled arrival is drawn in Self::new using whatever
mean the constructor received. Without resampling here, a chain like
PoissonSource::new(stops, schedule, 1, range).with_mean_interval(1200)
silently keeps the tick-0-ish arrival drawn at lambda = 1 — users
get their first rider ~1 tick in despite asking for one every 1200.
The method draws next_arrival_tick afresh from the updated mean,
anchored to the source’s current next_arrival_tick so that mid-
simulation calls do not rewind the anchor and trigger a catch-up
burst on the next generate. See
with_rng for the analogous rationale.
Sourcepub const fn next_arrival_tick(&self) -> u64
pub const fn next_arrival_tick(&self) -> u64
Tick of the next scheduled arrival.
Exposed so callers (and tests) can confirm when the next spawn is due without advancing the simulation.
Sourcepub fn with_rng(self, rng: StdRng) -> Self
pub fn with_rng(self, rng: StdRng) -> Self
Replace the internal RNG with a caller-supplied one.
Pair with a seeded rand::rngs::StdRng (via
StdRng::seed_from_u64(...)) to make PoissonSource output
reproducible across runs — closing the gap called out in
Snapshots and Determinism.
The next scheduled arrival is resampled from the new RNG, anchored
to the source’s current next_arrival_tick. That means:
- At construction time (the usual pattern, and what the doc
example shows) the anchor is still the tick-0-ish draw from
Self::new; resampling produces a fresh interval from there. - Mid-simulation — if
with_rngis called after the source has been stepped — the resample starts from the already-advanced anchor, so the next arrival is drawn forward from “now” rather than from tick 0. A naïvesample_next_arrival(0, ...)would rewind the anchor and cause the nextgenerate(tick)call to catch-up-emit every backlogged arrival in a single burst.
use elevator_core::traffic::{PoissonSource, TrafficPattern, TrafficSchedule};
use elevator_core::stop::StopId;
use rand::SeedableRng;
let seeded = rand::rngs::StdRng::seed_from_u64(42);
let source = PoissonSource::new(
vec![StopId(0), StopId(1)],
TrafficSchedule::constant(TrafficPattern::Uniform),
120,
(60.0, 90.0),
)
.with_rng(seeded);Sourcepub const fn with_weight_range(self, range: (f64, f64)) -> Self
pub const fn with_weight_range(self, range: (f64, f64)) -> Self
Replace the weight range.
If range.0 > range.1, the values are swapped.