mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 23:43:25 +03:00
moving RNG helpers from sim to abstutil
This commit is contained in:
parent
df5a151f8b
commit
b2e3f25393
@ -6,7 +6,9 @@ authors = ["Dustin Carlino <dabreegster@gmail.com>"]
|
||||
[dependencies]
|
||||
log = "0.4.5"
|
||||
multimap = "0.4.0"
|
||||
rand = { version = "0.5.1", features = ["serde1"] }
|
||||
serde = "1.0"
|
||||
serde_cbor = "0.8.2"
|
||||
serde_derive = "1.0"
|
||||
serde_json = "1.0"
|
||||
yansi = "0.4.0"
|
||||
|
@ -1,4 +1,5 @@
|
||||
use std::any::Any;
|
||||
use WeightedUsizeChoice;
|
||||
|
||||
// Trick to make a cloneable Any from
|
||||
// https://stackoverflow.com/questions/30353462/how-to-clone-a-struct-storing-a-boxed-trait-object/30353928#30353928.
|
||||
@ -34,3 +35,4 @@ impl Cloneable for usize {}
|
||||
impl Cloneable for f64 {}
|
||||
impl Cloneable for String {}
|
||||
impl Cloneable for (String, Box<Cloneable>) {}
|
||||
impl Cloneable for WeightedUsizeChoice {}
|
||||
|
@ -1,7 +1,10 @@
|
||||
extern crate log;
|
||||
extern crate multimap;
|
||||
extern crate rand;
|
||||
extern crate serde;
|
||||
extern crate serde_cbor;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
extern crate serde_json;
|
||||
extern crate yansi;
|
||||
|
||||
@ -11,6 +14,7 @@ mod collections;
|
||||
mod error;
|
||||
mod io;
|
||||
mod logs;
|
||||
mod random;
|
||||
mod time;
|
||||
|
||||
pub use abst_multimap::MultiMap;
|
||||
@ -23,6 +27,7 @@ pub use io::{
|
||||
write_json, FileWithProgress,
|
||||
};
|
||||
pub use logs::{format_log_record, LogAdapter};
|
||||
pub use random::{fork_rng, WeightedUsizeChoice};
|
||||
pub use time::{elapsed_seconds, Timer};
|
||||
|
||||
const PROGRESS_FREQUENCY_SECONDS: f64 = 0.2;
|
||||
|
41
abstutil/src/random.rs
Normal file
41
abstutil/src/random.rs
Normal file
@ -0,0 +1,41 @@
|
||||
use rand::distributions::{Distribution, Weighted, WeightedChoice};
|
||||
use rand::{RngCore, SeedableRng, XorShiftRng};
|
||||
|
||||
// Need to explain this trick -- basically keeps consistency between two different simulations when
|
||||
// each one might make slightly different sequences of calls to the RNG.
|
||||
pub fn fork_rng(base_rng: &mut XorShiftRng) -> XorShiftRng {
|
||||
XorShiftRng::from_seed([base_rng.next_u32() as u8; 16])
|
||||
}
|
||||
|
||||
// Represents the probability of sampling 0, 1, 2, 3... The sum can be anything.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct WeightedUsizeChoice {
|
||||
pub weights: Vec<u32>,
|
||||
}
|
||||
|
||||
impl WeightedUsizeChoice {
|
||||
pub fn parse(string: &str) -> Option<WeightedUsizeChoice> {
|
||||
let parts: Vec<&str> = string.split(",").collect();
|
||||
if parts.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let mut weights: Vec<u32> = Vec::new();
|
||||
for x in parts.into_iter() {
|
||||
let x = x.parse::<u32>().ok()?;
|
||||
weights.push(x);
|
||||
}
|
||||
Some(WeightedUsizeChoice { weights })
|
||||
}
|
||||
|
||||
pub fn sample(&self, rng: &mut XorShiftRng) -> u32 {
|
||||
let mut items: Vec<Weighted<u32>> = self
|
||||
.weights
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, pr)| Weighted {
|
||||
weight: *pr,
|
||||
item: idx as u32,
|
||||
}).collect();
|
||||
WeightedChoice::new(&mut items).sample(rng)
|
||||
}
|
||||
}
|
@ -28,14 +28,12 @@ pub mod turn_cycler;
|
||||
pub mod warp;
|
||||
|
||||
use abstutil;
|
||||
use abstutil::WeightedUsizeChoice;
|
||||
use downcast::Any;
|
||||
use ezgui::{Color, GfxCtx, WrappedWizard};
|
||||
use map_model::{IntersectionID, Map};
|
||||
use objects::{Ctx, ID};
|
||||
use sim::{
|
||||
ABTest, Neighborhood, NeighborhoodBuilder, OriginDestination, Scenario, Tick,
|
||||
WeightedUsizeChoice,
|
||||
};
|
||||
use sim::{ABTest, Neighborhood, NeighborhoodBuilder, OriginDestination, Scenario, Tick};
|
||||
use ui::PluginCtx;
|
||||
|
||||
pub trait Plugin: Any {
|
||||
|
@ -1,3 +1,4 @@
|
||||
use abstutil::WeightedUsizeChoice;
|
||||
use control::ControlMap;
|
||||
use driving::DrivingGoal;
|
||||
use map_model::{BuildingID, BusRoute, BusStopID, LaneID, Map, RoadID};
|
||||
@ -5,7 +6,7 @@ use std::collections::{BTreeSet, VecDeque};
|
||||
use walking::SidewalkSpot;
|
||||
use {
|
||||
BorderSpawnOverTime, CarID, Event, OriginDestination, PedestrianID, RouteID, Scenario,
|
||||
SeedParkedCars, Sim, SpawnOverTime, Tick, WeightedUsizeChoice,
|
||||
SeedParkedCars, Sim, SpawnOverTime, Tick,
|
||||
};
|
||||
|
||||
// Helpers to run the sim
|
||||
|
@ -58,7 +58,6 @@ pub use make::{
|
||||
OriginDestination, Scenario, SeedParkedCars, SimFlags, SpawnOverTime,
|
||||
};
|
||||
use map_model::{BuildingID, LaneID, Trace, TurnID};
|
||||
use rand::{RngCore, SeedableRng, XorShiftRng};
|
||||
pub use sim::{Benchmark, Sim, Summary};
|
||||
pub use stats::SimStats;
|
||||
use std::fmt;
|
||||
@ -335,42 +334,3 @@ impl Cloneable for Scenario {}
|
||||
impl Cloneable for Tick {}
|
||||
impl Cloneable for MapEdits {}
|
||||
impl Cloneable for ABTest {}
|
||||
impl Cloneable for WeightedUsizeChoice {}
|
||||
|
||||
fn fork_rng(base_rng: &mut XorShiftRng) -> XorShiftRng {
|
||||
XorShiftRng::from_seed([base_rng.next_u32() as u8; 16])
|
||||
}
|
||||
|
||||
// Represents the probability of sampling 0, 1, 2, 3... The sum can be anything.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct WeightedUsizeChoice {
|
||||
weights: Vec<u32>,
|
||||
}
|
||||
|
||||
impl WeightedUsizeChoice {
|
||||
pub fn parse(string: &str) -> Option<WeightedUsizeChoice> {
|
||||
let parts: Vec<&str> = string.split(",").collect();
|
||||
if parts.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let mut weights: Vec<u32> = Vec::new();
|
||||
for x in parts.into_iter() {
|
||||
let x = x.parse::<u32>().ok()?;
|
||||
weights.push(x);
|
||||
}
|
||||
Some(WeightedUsizeChoice { weights })
|
||||
}
|
||||
}
|
||||
|
||||
fn weighted_sample(choices: &WeightedUsizeChoice, rng: &mut XorShiftRng) -> u32 {
|
||||
use rand::distributions::{Distribution, Weighted, WeightedChoice};
|
||||
let mut items: Vec<Weighted<u32>> = choices
|
||||
.weights
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, pr)| Weighted {
|
||||
weight: *pr,
|
||||
item: idx as u32,
|
||||
}).collect();
|
||||
WeightedChoice::new(&mut items).sample(rng)
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
use abstutil;
|
||||
use abstutil::WeightedUsizeChoice;
|
||||
use driving::DrivingGoal;
|
||||
use map_model::{BuildingID, IntersectionID, LaneType, Map, RoadID};
|
||||
use rand::Rng;
|
||||
use rand::XorShiftRng;
|
||||
use std::collections::{BTreeSet, HashMap, HashSet};
|
||||
use walking::SidewalkSpot;
|
||||
use {CarID, Neighborhood, Sim, Tick, WeightedUsizeChoice};
|
||||
use {CarID, Neighborhood, Sim, Tick};
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||
pub struct Scenario {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use abstutil::elapsed_seconds;
|
||||
use abstutil::{elapsed_seconds, fork_rng, WeightedUsizeChoice};
|
||||
use dimensioned::si;
|
||||
use driving::{CreateCar, DrivingGoal, DrivingSimState};
|
||||
use kinematics::Vehicle;
|
||||
@ -12,8 +12,7 @@ use transit::TransitSimState;
|
||||
use trips::{TripLeg, TripManager};
|
||||
use walking::{SidewalkSpot, WalkingSimState};
|
||||
use {
|
||||
fork_rng, weighted_sample, AgentID, CarID, Distance, Event, ParkedCar, ParkingSpot,
|
||||
PedestrianID, RouteID, Tick, TripID, WeightedUsizeChoice,
|
||||
AgentID, CarID, Distance, Event, ParkedCar, ParkingSpot, PedestrianID, RouteID, Tick, TripID,
|
||||
};
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
|
||||
@ -329,7 +328,7 @@ impl Spawner {
|
||||
|
||||
let mut new_cars = 0;
|
||||
for b in owner_buildings {
|
||||
for _ in 0..weighted_sample(&cars_per_building, base_rng) {
|
||||
for _ in 0..cars_per_building.sample(base_rng) {
|
||||
if let Some(spot) =
|
||||
find_spot_near_building(*b, &mut open_spots_per_road, neighborhoods_roads, map)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user