prebaking gridlock results too

This commit is contained in:
Dustin Carlino 2019-11-01 20:22:39 -07:00
parent facd9c68b3
commit fa99c28d23
2 changed files with 95 additions and 73 deletions

View File

@ -8,7 +8,7 @@ use ezgui::{
};
use geom::{Duration, DurationHistogram, DurationStats};
use serde_derive::{Deserialize, Serialize};
use sim::{SimFlags, SimOptions, TripMode};
use sim::{Sim, SimFlags, SimOptions, TripMode};
use std::collections::BTreeMap;
// TODO Also have some kind of screenshot to display for each challenge
@ -130,21 +130,15 @@ impl State for ChallengeSplash {
}
}
// TODO Move all of this somewhere else, probably
pub fn prebake() {
let mut timer = Timer::new("prebake all challenge results");
let mut results = PrebakedResults {
faster_trips: BTreeMap::new(),
};
prebake_faster_trips(&mut results, "montlake", &mut timer);
abstutil::write_json("../data/prebaked_results.json", &results).unwrap();
}
fn prebake_faster_trips(results: &mut PrebakedResults, map_name: &str, timer: &mut Timer) {
timer.start(&format!("prebake faster trips on {}", map_name));
timer.start("run normal sim");
let (map, mut sim, _) = SimFlags {
load: abstutil::path1_bin(
map_name,
"montlake",
abstutil::SCENARIOS,
"weekday_typical_traffic_from_psrc",
),
@ -152,10 +146,31 @@ fn prebake_faster_trips(results: &mut PrebakedResults, map_name: &str, timer: &m
rng_seed: Some(42),
opts: SimOptions::new("prebaked"),
}
.load(timer);
sim.timed_step(&map, Duration::END_OF_DAY, timer);
.load(&mut timer);
sim.timed_step(&map, Duration::END_OF_DAY, &mut timer);
timer.stop("run normal sim");
timer.start("collect results");
let results = PrebakedResults {
faster_trips: FasterTrips::from(&sim),
gridlock_delays: GridlockDelays::from(&sim),
};
abstutil::write_json("../data/prebaked_results.json", &results).unwrap();
}
// TODO Something more general?
// - key by GameplayMode (which needs map name too maybe)
// - different baselines/benchmarks
#[derive(Serialize, Deserialize)]
pub struct PrebakedResults {
pub faster_trips: FasterTrips,
pub gridlock_delays: GridlockDelays,
}
#[derive(Serialize, Deserialize)]
pub struct FasterTrips(pub BTreeMap<TripMode, DurationStats>);
impl FasterTrips {
pub fn from(sim: &Sim) -> FasterTrips {
let mut distribs: BTreeMap<TripMode, DurationHistogram> = BTreeMap::new();
for m in vec![
TripMode::Walk,
@ -168,18 +183,37 @@ fn prebake_faster_trips(results: &mut PrebakedResults, map_name: &str, timer: &m
for (_, m, dt) in sim.get_finished_trips().finished_trips {
distribs.get_mut(&m).unwrap().add(dt);
}
let mut results = BTreeMap::new();
for (m, distrib) in distribs {
results.faster_trips.insert(m, distrib.to_stats());
results.insert(m, distrib.to_stats());
}
FasterTrips(results)
}
timer.stop("collect results");
timer.stop(&format!("prebake faster trips on {}", map_name));
}
// TODO Something more general?
// - key by GameplayMode (which needs map name too maybe)
// - different baselines/benchmarks
#[derive(Serialize, Deserialize)]
pub struct PrebakedResults {
pub faster_trips: BTreeMap<TripMode, DurationStats>,
pub struct GridlockDelays {
pub lt_1m: usize,
pub lt_5m: usize,
pub stuck: usize,
}
impl GridlockDelays {
pub fn from(sim: &Sim) -> GridlockDelays {
let mut delays = GridlockDelays {
lt_1m: 0,
lt_5m: 0,
stuck: 0,
};
for a in sim.get_agent_metadata() {
if a.time_spent_blocked < Duration::minutes(1) {
delays.lt_1m += 1;
} else if a.time_spent_blocked < Duration::minutes(5) {
delays.lt_5m += 1;
} else {
delays.stuck += 1;
}
}
delays
}
}

View File

@ -1,4 +1,4 @@
use crate::challenges::PrebakedResults;
use crate::challenges::{FasterTrips, GridlockDelays, PrebakedResults};
use crate::game::{msg, Transition, WizardState};
use crate::render::AgentColorScheme;
use crate::sandbox::{analytics, bus_explorer, spawner, SandboxMode};
@ -313,7 +313,7 @@ impl GameplayState {
if *time != ui.primary.sim.time() {
*time = ui.primary.sim.time();
self.menu.set_info(ctx, gridlock_panel(ui));
self.menu.set_info(ctx, gridlock_panel(ui, &self.prebaked));
}
if self.menu.action("help") {
@ -373,62 +373,50 @@ fn bus_route_panel(id: BusRouteID, ui: &UI, stat: Statistic) -> Text {
txt
}
fn gridlock_panel(ui: &UI) -> Text {
let mut lt_1m = 0;
let mut lt_5m = 0;
let mut stuck = 0;
for a in ui.primary.sim.get_agent_metadata() {
if a.time_spent_blocked < Duration::minutes(1) {
lt_1m += 1;
} else if a.time_spent_blocked < Duration::minutes(5) {
lt_5m += 1;
} else {
stuck += 1;
}
}
let total = (lt_1m + lt_5m + stuck) as f64;
fn gridlock_panel(ui: &UI, prebaked: &PrebakedResults) -> Text {
let now = GridlockDelays::from(&ui.primary.sim);
let baseline = &prebaked.gridlock_delays;
let now_total = (now.lt_1m + now.lt_5m + now.stuck) as f64;
let baseline_total = (baseline.lt_1m + baseline.lt_5m + baseline.stuck) as f64;
let mut txt = Text::new();
txt.add(Line("How long have agents been stuck?"));
txt.add(Line(format!(
"under 1 min: {} ({:.1}%)",
prettyprint_usize(lt_1m),
(lt_1m as f64) / total * 100.0
"under 1 min: {} ({:.1}%, vs {:.1}%)",
prettyprint_usize(now.lt_1m),
(now.lt_1m as f64) / now_total * 100.0,
(baseline.lt_1m as f64) / baseline_total * 100.0
)));
txt.add(Line(format!(
"under 5 mins: {} ({:.1}%)",
prettyprint_usize(lt_5m),
(lt_5m as f64) / total * 100.0
"under 5 mins: {} ({:.1}%, vs {:.1}%)",
prettyprint_usize(now.lt_5m),
(now.lt_5m as f64) / now_total * 100.0,
(baseline.lt_5m as f64) / baseline_total * 100.0
)));
txt.add(Line(format!(
"over 5 mins: {} ({:.1}%)",
prettyprint_usize(stuck),
(stuck as f64) / total * 100.0
"over 5 mins: {} ({:.1}%, vs {:.1}%)",
prettyprint_usize(now.stuck),
(now.stuck as f64) / now_total * 100.0,
(baseline.stuck as f64) / baseline_total * 100.0
)));
txt
}
fn faster_trips_panel(mode: TripMode, ui: &UI, prebaked: &PrebakedResults) -> Text {
let mut distrib: DurationHistogram = Default::default();
for (_, m, dt) in ui.primary.sim.get_finished_trips().finished_trips {
if mode == m {
distrib.add(dt);
}
}
let stats = distrib.to_stats();
let baseline = &prebaked.faster_trips[&mode];
let now = &FasterTrips::from(&ui.primary.sim).0[&mode];
let baseline = &prebaked.faster_trips.0[&mode];
let mut txt = Text::new();
txt.add(Line(format!(
"{} finished {:?} trips (vs {})",
prettyprint_usize(stats.count),
prettyprint_usize(now.count),
mode,
prettyprint_usize(baseline.count),
)));
// TODO Which one?
if false {
for (stat, dt) in &stats.stats {
for (stat, dt) in &now.stats {
txt.add(Line(format!("{}: ", stat)));
let vs = baseline.stats[&stat];
let color = if *dt <= vs { Color::GREEN } else { Color::RED };
@ -437,14 +425,14 @@ fn faster_trips_panel(mode: TripMode, ui: &UI, prebaked: &PrebakedResults) -> Te
}
}
if true {
for (stat, dt) in stats.stats {
for (stat, dt) in &now.stats {
txt.add(Line(format!("{}: ", stat)));
let vs = baseline.stats[&stat];
if dt <= vs {
txt.append(Line((vs - dt).minimal_tostring()).fg(Color::GREEN));
if *dt <= vs {
txt.append(Line((vs - *dt).minimal_tostring()).fg(Color::GREEN));
txt.append(Line(" faster"));
} else {
txt.append(Line((dt - vs).minimal_tostring()).fg(Color::RED));
txt.append(Line((*dt - vs).minimal_tostring()).fg(Color::RED));
txt.append(Line(" slower"));
}
}