Skip to main content

PoissonSource

Struct PoissonSource 

Source
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

Source

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.

Source

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.

Source

pub fn with_schedule(self, schedule: TrafficSchedule) -> Self

Replace the traffic schedule.

Source

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.

Source

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.

Source

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_rng is 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ïve sample_next_arrival(0, ...) would rewind the anchor and cause the next generate(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);
Source

pub const fn with_weight_range(self, range: (f64, f64)) -> Self

Replace the weight range.

If range.0 > range.1, the values are swapped.

Trait Implementations§

Source§

impl Debug for PoissonSource

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl TrafficSource for PoissonSource

Source§

fn generate(&mut self, tick: u64) -> Vec<SpawnRequest>

Generate spawn requests for the given tick. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.