pub struct RsrDispatch {
pub eta_weight: f64,
pub wrong_direction_penalty: f64,
pub coincident_car_call_bonus: f64,
pub load_penalty_coeff: f64,
pub peak_direction_multiplier: f64,
}Expand description
Additive RSR-style cost stack. Lower scores win the Hungarian assignment.
See module docs for the cost shape. All weights default to 0.0
except eta_weight (1.0), giving a baseline that mirrors
NearestCarDispatch until terms are
opted in.
§Weight invariants
Every weight field must be finite and non-negative. The
with_* builder methods enforce this with assert!; direct field
mutation bypasses the check and is a caller responsibility. A NaN weight propagates through the multiply-add
chain and silently collapses every pair’s cost to zero (Rust’s
NaN.max(0.0) == 0.0), producing an arbitrary but type-valid
assignment from the Hungarian solver — a hard bug to diagnose.
Fields§
§eta_weight: f64Weight on travel_time = distance / max_speed (seconds).
Default 1.0; raising it shifts the blend toward travel time.
wrong_direction_penalty: f64Constant added when the candidate stop lies opposite the car’s committed travel direction.
Default 0.0; the Otis RSR lineage uses a large value so any
right-direction candidate outranks any wrong-direction one.
Ignored for cars in ElevatorPhase::Idle or stopped phases,
since an idle car has no committed direction to be opposite to.
coincident_car_call_bonus: f64Bonus subtracted when the candidate stop is already a car-call inside this car.
Merges the new pickup with an existing dropoff instead of
spawning an unrelated trip. Default 0.0. Read from
DispatchManifest::car_calls_for.
load_penalty_coeff: f64Coefficient on a smooth load-fraction penalty
(load_penalty_coeff · load_ratio).
Fires for partially loaded cars below the bypass_load_*_pct
threshold enforced by pair_can_do_work; lets you prefer
emptier cars for new pickups without an on/off cliff.
Default 0.0.
peak_direction_multiplier: f64Multiplier applied to wrong_direction_penalty when the
TrafficDetector classifies the current tick as
TrafficMode::UpPeak or TrafficMode::DownPeak.
Default 1.0 (mode-agnostic — behaviour identical to pre-peak
tuning). Raising it strengthens directional commitment during
peaks where a car carrying a lobby-bound load shouldn’t be
pulled backwards to grab a new pickup. Off-peak periods keep
the unscaled penalty, leaving inter-floor assignments free
to reverse cheaply.
Silently reduces to 1.0 when no TrafficDetector resource
is installed — tests and custom sims that bypass the auto-install
stay unaffected.
Implementations§
Source§impl RsrDispatch
impl RsrDispatch
Sourcepub const fn new() -> Self
pub const fn new() -> Self
Create a new RsrDispatch with the baseline weights
(eta_weight = 1.0, all penalties/bonuses disabled).
Sourcepub fn with_wrong_direction_penalty(self, weight: f64) -> Self
pub fn with_wrong_direction_penalty(self, weight: f64) -> Self
Set the wrong-direction penalty.
§Panics
Panics on non-finite or negative weights — a negative penalty would invert the direction ordering, silently preferring wrong-direction candidates.
Sourcepub fn with_coincident_car_call_bonus(self, weight: f64) -> Self
pub fn with_coincident_car_call_bonus(self, weight: f64) -> Self
Set the coincident-car-call bonus.
§Panics
Panics on non-finite or negative weights — the bonus is subtracted, so a negative value would become a penalty.
Sourcepub fn with_load_penalty_coeff(self, weight: f64) -> Self
pub fn with_load_penalty_coeff(self, weight: f64) -> Self
Sourcepub fn with_eta_weight(self, weight: f64) -> Self
pub fn with_eta_weight(self, weight: f64) -> Self
Set the ETA weight.
§Panics
Panics on non-finite or negative weights. Zero is allowed and reduces the strategy to penalty/bonus tiebreaking alone.
Sourcepub fn with_peak_direction_multiplier(self, factor: f64) -> Self
pub fn with_peak_direction_multiplier(self, factor: f64) -> Self
Set the peak-direction multiplier.
§Panics
Panics on non-finite or sub-1.0 values. A multiplier below 1.0
would weaken the direction penalty during peaks (the opposite
of the intent) — explicitly disallowed so a typo doesn’t silently
invert the tuning.