diff --git a/abstutil/Cargo.toml b/abstutil/Cargo.toml index f61acbd62e..8c539787bb 100644 --- a/abstutil/Cargo.toml +++ b/abstutil/Cargo.toml @@ -8,7 +8,8 @@ edition = "2018" lazy_static = "1.1.0" log = "0.4.5" multimap = "0.4.0" -rand = { version = "0.5.1", features = ["serde1"] } +rand = { version = "0.6.4", features = ["serde1"] } +rand_xorshift = "0.1.1" serde = "1.0" serde_cbor = "0.8.2" serde_derive = "1.0" diff --git a/abstutil/src/random.rs b/abstutil/src/random.rs index 64dc6e76de..2bc6534804 100644 --- a/abstutil/src/random.rs +++ b/abstutil/src/random.rs @@ -1,5 +1,6 @@ -use rand::distributions::{Distribution, Weighted, WeightedChoice}; -use rand::{RngCore, SeedableRng, XorShiftRng}; +use rand::distributions::{Distribution, WeightedIndex}; +use rand::{RngCore, SeedableRng}; +use rand_xorshift::XorShiftRng; use serde_derive::{Deserialize, Serialize}; // Need to explain this trick -- basically keeps consistency between two different simulations when @@ -11,7 +12,7 @@ pub fn fork_rng(base_rng: &mut XorShiftRng) -> XorShiftRng { // 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, + pub weights: Vec, } impl WeightedUsizeChoice { @@ -20,24 +21,15 @@ impl WeightedUsizeChoice { if parts.is_empty() { return None; } - let mut weights: Vec = Vec::new(); + let mut weights: Vec = Vec::new(); for x in parts.into_iter() { - let x = x.parse::().ok()?; + let x = x.parse::().ok()?; weights.push(x); } Some(WeightedUsizeChoice { weights }) } - pub fn sample(&self, rng: &mut XorShiftRng) -> u32 { - let mut items: Vec> = self - .weights - .iter() - .enumerate() - .map(|(idx, pr)| Weighted { - weight: *pr, - item: idx as u32, - }) - .collect(); - WeightedChoice::new(&mut items).sample(rng) + pub fn sample(&self, rng: &mut XorShiftRng) -> usize { + WeightedIndex::new(&self.weights).unwrap().sample(rng) } } diff --git a/convert_osm/Cargo.toml b/convert_osm/Cargo.toml index 5d89e63e6f..2ab8f64acc 100644 --- a/convert_osm/Cargo.toml +++ b/convert_osm/Cargo.toml @@ -14,7 +14,7 @@ geojson = "0.12.0" geom = { path = "../geom" } gtfs = { path = "../gtfs" } kml = { path = "../kml" } -ordered-float = "0.5.0" +ordered-float = "1.0.1" osm-xml = "0.5.1" map_model = { path = "../map_model" } pretty_assertions = "0.5.1" diff --git a/convert_osm/src/lib.rs b/convert_osm/src/lib.rs index bb47ff5c4e..9313125552 100644 --- a/convert_osm/src/lib.rs +++ b/convert_osm/src/lib.rs @@ -10,7 +10,7 @@ use dimensioned::si; use geom::{GPSBounds, PolyLine, Pt2D}; use kml::ExtraShapes; use map_model::{raw_data, FindClosest, IntersectionType, LANE_THICKNESS}; -use ordered_float::NotNaN; +use ordered_float::NotNan; use std::path::Path; use structopt::StructOpt; @@ -104,7 +104,7 @@ pub fn convert(flags: &Flags, timer: &mut abstutil::Timer) -> raw_data::Map { let closest_intersection = map .intersections .iter_mut() - .min_by_key(|i| NotNaN::new(distance(i)).unwrap()) + .min_by_key(|i| NotNan::new(distance(i)).unwrap()) .unwrap(); let dist = distance(closest_intersection); if dist <= MAX_METERS_BTWN_INTERSECTION_AND_SIGNAL { diff --git a/docs/development.md b/docs/development.md new file mode 100644 index 0000000000..6ac4dcc1ee --- /dev/null +++ b/docs/development.md @@ -0,0 +1,3 @@ +# Development notes + +Find packages to upgrade: `cargo outdated -R` diff --git a/editor/Cargo.toml b/editor/Cargo.toml index e84bab3292..e9463c6ded 100644 --- a/editor/Cargo.toml +++ b/editor/Cargo.toml @@ -19,10 +19,10 @@ kml = { path = "../kml" } lazy_static = "1.1.0" log = "0.4.5" map_model = { path = "../map_model" } -ordered-float = "0.5.0" +ordered-float = "1.0.1" pretty_assertions = "0.5.1" quick-xml = "0.10.0" -rand = "0.5.1" +rand = "0.6.4" serde = "1.0" serde_derive = "1.0" sim = { path = "../sim" } diff --git a/editor/src/render/intersection.rs b/editor/src/render/intersection.rs index 54d3cbdb01..e0b0b6470b 100644 --- a/editor/src/render/intersection.rs +++ b/editor/src/render/intersection.rs @@ -7,7 +7,7 @@ use map_model::{ Cycle, Intersection, IntersectionID, IntersectionType, Map, TurnPriority, TurnType, LANE_THICKNESS, }; -use ordered_float::NotNaN; +use ordered_float::NotNan; #[derive(Debug)] pub struct DrawIntersection { @@ -216,7 +216,7 @@ pub fn draw_signal_diagram( let label_length = labels .iter() .map(|l| ctx.canvas.text_dims(l).0) - .max_by_key(|w| NotNaN::new(*w).unwrap()) + .max_by_key(|w| NotNan::new(*w).unwrap()) .unwrap(); let total_screen_width = (intersection_width * zoom) + label_length + 10.0; let x1_screen = ctx.canvas.window_width - total_screen_width; diff --git a/ezgui/Cargo.toml b/ezgui/Cargo.toml index fcc2d66382..043a52a90e 100644 --- a/ezgui/Cargo.toml +++ b/ezgui/Cargo.toml @@ -9,7 +9,7 @@ abstutil = { path = "../abstutil" } dimensioned = { git = "https://github.com/paholg/dimensioned", rev = "0e1076ebfa5128d1ee544bdc9754c948987b6fe3", features = ["serde"] } geom = { path = "../geom" } log = "0.4.5" -ordered-float = "0.5.0" +ordered-float = "1.0.1" palette = "0.4" piston = "0.37.0" piston2d-graphics = "0.26.0" diff --git a/ezgui/src/text.rs b/ezgui/src/text.rs index d82b314f65..9254d85a6a 100644 --- a/ezgui/src/text.rs +++ b/ezgui/src/text.rs @@ -6,7 +6,7 @@ use graphics; use graphics::character::CharacterCache; use graphics::{Rectangle, Transformed}; use opengl_graphics::GlyphCache; -use ordered_float::NotNaN; +use ordered_float::NotNan; use textwrap; const FG_COLOR: Color = Color::WHITE; @@ -141,7 +141,7 @@ impl Text { ) .unwrap() }) - .max_by_key(|w| NotNaN::new(*w).unwrap()) + .max_by_key(|w| NotNan::new(*w).unwrap()) .unwrap(); let height = (self.lines.len() as f64) * LINE_HEIGHT; (width, height) diff --git a/geom/Cargo.toml b/geom/Cargo.toml index c89c3a0858..3ae3ffe23f 100644 --- a/geom/Cargo.toml +++ b/geom/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" aabb-quadtree = "0.1.0" dimensioned = { git = "https://github.com/paholg/dimensioned", rev = "0e1076ebfa5128d1ee544bdc9754c948987b6fe3", features = ["serde"] } geo = "0.10.2" -ordered-float = "0.5.0" -rand = "0.5.1" +ordered-float = "1.0.1" +rand = "0.6.4" serde = "1.0" serde_derive = "1.0" diff --git a/geom/src/polyline.rs b/geom/src/polyline.rs index ffbb090e30..d5428239c4 100644 --- a/geom/src/polyline.rs +++ b/geom/src/polyline.rs @@ -1,6 +1,6 @@ use crate::{line_intersection, Angle, Bounds, Line, Polygon, Pt2D, Triangle, EPSILON_DIST}; use dimensioned::si; -use ordered_float::NotNaN; +use ordered_float::NotNan; use serde_derive::{Deserialize, Serialize}; use std::f64; use std::fmt; @@ -360,7 +360,7 @@ impl PolyLine { hits.sort_by_key(|(pt, _)| { let mut copy = self.clone(); copy.trim_to_pt(*pt); - NotNaN::new(copy.length().value_unsafe).unwrap() + NotNan::new(copy.length().value_unsafe).unwrap() }); if !hits.is_empty() { return Some(hits[0]); diff --git a/geom/src/pt.rs b/geom/src/pt.rs index 583630aa37..d73fd5e0f1 100644 --- a/geom/src/pt.rs +++ b/geom/src/pt.rs @@ -1,6 +1,6 @@ use crate::{Angle, GPSBounds, LonLat}; use aabb_quadtree::geom::{Point, Rect}; -use ordered_float::NotNaN; +use ordered_float::NotNan; use serde_derive::{Deserialize, Serialize}; use std::f64; use std::fmt; @@ -130,15 +130,15 @@ impl From for Pt2D { // TODO So rename it HashablePair or something #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] pub struct HashablePt2D { - x_nan: NotNaN, - y_nan: NotNaN, + x_nan: NotNan, + y_nan: NotNan, } impl HashablePt2D { pub fn new(x: f64, y: f64) -> HashablePt2D { HashablePt2D { - x_nan: NotNaN::new(x).unwrap(), - y_nan: NotNaN::new(y).unwrap(), + x_nan: NotNan::new(x).unwrap(), + y_nan: NotNan::new(y).unwrap(), } } diff --git a/map_model/Cargo.toml b/map_model/Cargo.toml index b8b0b4b369..0fb423018e 100644 --- a/map_model/Cargo.toml +++ b/map_model/Cargo.toml @@ -14,7 +14,7 @@ gtfs = { path = "../gtfs" } log = "0.4.5" multimap = "0.4.0" nbez = "0.1.0" -ordered-float = "0.5.0" +ordered-float = "1.0.1" pretty_assertions = "0.5.1" serde = "1.0" serde_derive = "1.0" diff --git a/map_model/src/find_closest.rs b/map_model/src/find_closest.rs index e1f50de48e..10c989e8e5 100644 --- a/map_model/src/find_closest.rs +++ b/map_model/src/find_closest.rs @@ -4,7 +4,7 @@ use dimensioned::si; use geo; use geo::prelude::{ClosestPoint, EuclideanDistance}; use geom::{Bounds, PolyLine, Pt2D}; -use ordered_float::NotNaN; +use ordered_float::NotNan; use std::collections::HashMap; // TODO Refactor and generalize all of this... @@ -55,7 +55,7 @@ where { let dist = pt.euclidean_distance(&query_geom); if dist * si::M <= max_dist_away { - Some((key, pt, NotNaN::new(dist).unwrap())) + Some((key, pt, NotNan::new(dist).unwrap())) } else { None } @@ -80,7 +80,7 @@ where .query(query_bbox) .into_iter() .min_by_key(|(key, _, _)| { - NotNaN::new(query_geom.euclidean_distance(&self.geometries[key])).unwrap() + NotNan::new(query_geom.euclidean_distance(&self.geometries[key])).unwrap() }).map(|(key, _, _)| key.clone()) }*/ } diff --git a/map_model/src/make/bus_stops.rs b/map_model/src/make/bus_stops.rs index 29d2947837..19cbca0c86 100644 --- a/map_model/src/make/bus_stops.rs +++ b/map_model/src/make/bus_stops.rs @@ -8,7 +8,7 @@ use dimensioned::si; use geom::{Bounds, GPSBounds, HashablePt2D, Pt2D}; use gtfs; use multimap::MultiMap; -use ordered_float::NotNaN; +use ordered_float::NotNan; use std::collections::{BTreeMap, HashMap, HashSet}; use std::iter; @@ -46,7 +46,7 @@ pub fn make_bus_stops( if let Ok(driving_lane) = road.find_closest_lane(*id, vec![LaneType::Driving, LaneType::Bus]) { - dists.sort_by_key(|(dist, _)| NotNaN::new(dist.value_unsafe).unwrap()); + dists.sort_by_key(|(dist, _)| NotNan::new(dist.value_unsafe).unwrap()); for (idx, (dist_along, orig_pt)) in dists.iter().enumerate() { let stop_id = BusStopID { sidewalk: *id, idx }; point_to_stop_id.insert(*orig_pt, stop_id); diff --git a/map_model/src/pathfind.rs b/map_model/src/pathfind.rs index a3a611aa48..98511289aa 100644 --- a/map_model/src/pathfind.rs +++ b/map_model/src/pathfind.rs @@ -1,7 +1,7 @@ use crate::{BusRouteID, BusStopID, LaneID, LaneType, Map, Position, Traversable, TurnID}; use dimensioned::si; use geom::{Line, PolyLine, Pt2D}; -use ordered_float::NotNaN; +use ordered_float::NotNan; use serde_derive::{Deserialize, Serialize}; use std::collections::{BinaryHeap, HashMap, VecDeque}; @@ -389,7 +389,7 @@ impl Pathfinder { } // This should be deterministic, since cost ties would be broken by PathStep. - let mut queue: BinaryHeap<(NotNaN, InternalPathStep)> = BinaryHeap::new(); + let mut queue: BinaryHeap<(NotNan, InternalPathStep)> = BinaryHeap::new(); let start_len = map.get_l(start.lane()).length(); if map.get_l(start.lane()).is_sidewalk() { if start.dist_along() != start_len { @@ -492,6 +492,6 @@ fn validate(map: &Map, steps: &Vec) { } // Negate since BinaryHeap is a max-heap. -fn dist_to_pri_queue(dist: si::Meter) -> NotNaN { - NotNaN::new(-1.0 * dist.value_unsafe).unwrap() +fn dist_to_pri_queue(dist: si::Meter) -> NotNan { + NotNan::new(-1.0 * dist.value_unsafe).unwrap() } diff --git a/sim/Cargo.toml b/sim/Cargo.toml index f7d321427d..03d5e85a4a 100644 --- a/sim/Cargo.toml +++ b/sim/Cargo.toml @@ -15,9 +15,10 @@ log = "0.4.5" map_model = { path = "../map_model" } more-asserts = "0.2.1" multimap = "0.4.0" -ordered-float = "0.5.0" +ordered-float = "1.0.1" pretty_assertions = "0.5.1" -rand = { version = "0.5.1", features = ["serde1"] } +rand = { version = "0.6.4", features = ["serde1"] } +rand_xorshift = "0.1.1" rayon = "1.0" regex = "1.0.6" serde = "1.0" diff --git a/sim/src/driving.rs b/sim/src/driving.rs index fefee658c9..388ba302a8 100644 --- a/sim/src/driving.rs +++ b/sim/src/driving.rs @@ -18,8 +18,8 @@ use map_model::{ LANE_THICKNESS, }; use multimap::MultiMap; -use ordered_float::NotNaN; -use rand::XorShiftRng; +use ordered_float::NotNan; +use rand_xorshift::XorShiftRng; use serde_derive::{Deserialize, Serialize}; use std; use std::collections::{BTreeMap, HashSet}; @@ -258,7 +258,7 @@ impl Car { let safe_accel = vehicle.clamp_accel( constraints .into_iter() - .min_by_key(|a| NotNaN::new(a.value_unsafe).unwrap()) + .min_by_key(|a| NotNan::new(a.value_unsafe).unwrap()) .unwrap(), ); if self.debug { @@ -384,7 +384,7 @@ impl SimQueue { let mut cars_queue: Vec<(Distance, CarID)> = ids.iter().map(|id| (cars[id].dist_along, *id)).collect(); // Sort descending. - cars_queue.sort_by_key(|(dist, _)| -NotNaN::new(dist.value_unsafe).unwrap()); + cars_queue.sort_by_key(|(dist, _)| -NotNan::new(dist.value_unsafe).unwrap()); let capacity = ((id.length(map) / Vehicle::best_case_following_dist()).ceil() as usize).max(1); diff --git a/sim/src/kinematics.rs b/sim/src/kinematics.rs index 9909438542..6de33de9fb 100644 --- a/sim/src/kinematics.rs +++ b/sim/src/kinematics.rs @@ -3,7 +3,8 @@ use abstutil::Error; use dimensioned::si; use geom::EPSILON_DIST; use more_asserts::assert_ge; -use rand::{Rng, XorShiftRng}; +use rand::Rng; +use rand_xorshift::XorShiftRng; use serde_derive::{Deserialize, Serialize}; use std; diff --git a/sim/src/make/scenario.rs b/sim/src/make/scenario.rs index 7b8e18a9bb..0baf3cc06d 100644 --- a/sim/src/make/scenario.rs +++ b/sim/src/make/scenario.rs @@ -4,7 +4,9 @@ use crate::{CarID, Neighborhood, Sim, Tick}; use abstutil; use abstutil::WeightedUsizeChoice; use map_model::{BuildingID, IntersectionID, LaneType, Map, Pathfinder, RoadID}; -use rand::{Rng, XorShiftRng}; +use rand::seq::SliceRandom; +use rand::Rng; +use rand_xorshift::XorShiftRng; use serde_derive::{Deserialize, Serialize}; use std::collections::{BTreeSet, HashMap, HashSet}; @@ -110,9 +112,8 @@ impl Scenario { let spawn_time = Tick::uniform(s.start_tick, s.stop_tick, &mut sim.rng); // Note that it's fine for agents to start/end at the same building. Later we might // want a better assignment of people per household, or workers per office building. - let from_bldg = *sim - .rng - .choose(&bldgs_per_neighborhood[&s.start_from_neighborhood]) + let from_bldg = *bldgs_per_neighborhood[&s.start_from_neighborhood] + .choose(&mut sim.rng) .unwrap(); // What mode? @@ -314,7 +315,7 @@ impl OriginDestination { match self { OriginDestination::Neighborhood(ref n) => { if let Some(bldgs) = bldgs_per_neighborhood.get(n) { - Some(DrivingGoal::ParkNear(*rng.choose(bldgs).unwrap())) + Some(DrivingGoal::ParkNear(*bldgs.choose(rng).unwrap())) } else { panic!("Neighborhood {} isn't defined", n); } @@ -345,7 +346,7 @@ impl OriginDestination { match self { OriginDestination::Neighborhood(ref n) => { if let Some(bldgs) = bldgs_per_neighborhood.get(n) { - Some(DrivingGoal::ParkNear(*rng.choose(bldgs).unwrap())) + Some(DrivingGoal::ParkNear(*bldgs.choose(rng).unwrap())) } else { panic!("Neighborhood {} isn't defined", n); } @@ -375,7 +376,7 @@ impl OriginDestination { match self { OriginDestination::Neighborhood(ref n) => { if let Some(bldgs) = bldgs_per_neighborhood.get(n) { - Some(SidewalkSpot::building(*rng.choose(bldgs).unwrap(), map)) + Some(SidewalkSpot::building(*bldgs.choose(rng).unwrap(), map)) } else { panic!("Neighborhood {} isn't defined", n); } diff --git a/sim/src/physics.rs b/sim/src/physics.rs index c4828eb1a6..ef3987d938 100644 --- a/sim/src/physics.rs +++ b/sim/src/physics.rs @@ -1,6 +1,7 @@ use dimensioned::si; use lazy_static::lazy_static; -use rand::{Rng, XorShiftRng}; +use rand::Rng; +use rand_xorshift::XorShiftRng; use regex::Regex; use serde_derive::{Deserialize, Serialize}; diff --git a/sim/src/router.rs b/sim/src/router.rs index 6f862b4b7d..2f4dfe85dd 100644 --- a/sim/src/router.rs +++ b/sim/src/router.rs @@ -10,7 +10,8 @@ use geom::EPSILON_DIST; use map_model::{ BuildingID, LaneID, LaneType, Map, Path, PathStep, Position, Trace, Traversable, TurnID, }; -use rand::{Rng, XorShiftRng}; +use rand::seq::SliceRandom; +use rand_xorshift::XorShiftRng; use serde_derive::{Deserialize, Serialize}; #[derive(Clone, PartialEq, Serialize, Deserialize)] @@ -204,7 +205,7 @@ impl Router { error!("{} can't find parking on {}, and also it's a dead-end, so they'll be stuck there forever. Vanishing.", view.id, last_lane); return Some(Action::TmpVanish); } - let (turn, new_lane) = rng.choose(&choices).unwrap(); + let (turn, new_lane) = choices.choose(rng).unwrap(); if view.debug { debug!( "{} can't find parking on {}, so wandering over to {}", diff --git a/sim/src/sim.rs b/sim/src/sim.rs index 6b0c69fa1f..26026edca7 100644 --- a/sim/src/sim.rs +++ b/sim/src/sim.rs @@ -15,7 +15,8 @@ use abstutil; use abstutil::Error; use derivative::Derivative; use map_model::{BuildingID, IntersectionID, LaneID, LaneType, Map, Path, Trace, Turn}; -use rand::{FromEntropy, SeedableRng, XorShiftRng}; +use rand::{FromEntropy, SeedableRng}; +use rand_xorshift::XorShiftRng; use serde_derive::{Deserialize, Serialize}; use std; use std::collections::HashSet; diff --git a/sim/src/spawn.rs b/sim/src/spawn.rs index d5625dc8e0..c15f1f81b0 100644 --- a/sim/src/spawn.rs +++ b/sim/src/spawn.rs @@ -15,7 +15,8 @@ use map_model::{ BuildingID, BusRoute, BusRouteID, BusStopID, LaneID, LaneType, Map, Path, PathRequest, Pathfinder, Position, RoadID, }; -use rand::{Rng, XorShiftRng}; +use rand::seq::SliceRandom; +use rand_xorshift::XorShiftRng; use serde_derive::{Deserialize, Serialize}; use std::collections::{BTreeSet, HashMap, HashSet, VecDeque}; @@ -394,7 +395,7 @@ impl Spawner { } } total_spots += spots.len(); - fork_rng(base_rng).shuffle(&mut spots); + spots.shuffle(&mut fork_rng(base_rng)); open_spots_per_road.insert(r.id, spots); } diff --git a/tests/Cargo.toml b/tests/Cargo.toml index ec3dd36955..7b22514695 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -12,7 +12,7 @@ gag = "0.1.10" geom = { path = "../geom" } log = "0.4.5" map_model = { path = "../map_model" } -rand = "0.5.1" +rand = "0.6.4" sim = { path = "../sim" } structopt = "0.2" termion = "1.5.1"