mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-28 12:12:00 +03:00
prebaking gridlock results too
This commit is contained in:
parent
facd9c68b3
commit
fa99c28d23
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user