From 470a672afbac1b70ead57182969361f1c8cd122c Mon Sep 17 00:00:00 2001 From: arnekeller Date: Sun, 7 Apr 2019 16:30:22 +0200 Subject: [PATCH] Optimize path finding --- src/main.rs | 68 +++++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/src/main.rs b/src/main.rs index 25ea7f8..877bb4a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ use std::f32; use std::hash::{Hash, Hasher}; use std::process::exit; use std::sync::RwLock; +use std::time::{self, Instant}; mod display; mod input; @@ -26,7 +27,7 @@ type Polygon = geo::Polygon; struct Opt { /// Debug-Modus aktivieren #[structopt(short = "d", long = "debug")] - _debug: bool, + debug: bool, /// Zwischenlösungen speichern #[structopt(short = "s", long = "save")] _save_intermediates: bool, @@ -130,11 +131,15 @@ fn main() { "Theoretisches Maximum: {:?}", calc_time(distance(meeting_point, house), meeting_point.y()) ); - - let mut best = dijkstra( - &vec![start], - |state| { - let last = &state[0]; + + // Performanzmessung + let mut iterations = 0; + let mut time = time::Duration::from_secs(0); + + let best = dijkstra( + &start, + |last| { + let start = Instant::now(); // neue Zustände let mut all = vec![]; @@ -142,24 +147,21 @@ fn main() { for &next in points .iter() // Ecke sollte nicht schon in Route sein - .filter(|&&next| !state.iter().any(|p| p.pos == next)) + //.filter(|&&next| !state.iter().any(|p| p.pos == next)) // Weg zu dieser Ecke sollte kein Polygon schneiden .filter(|&&next| none_intersect(Line::new(last.pos, next))) { // Lisa könnte zu dieser Ecke rennen let total_distance = last.total_distance + distance(last.pos, next); let bus = best_bus_pos(&opt, total_distance, next); - let mut route = state.clone(); - route.insert( - 0, - RunState { - pos: next, - bus, - total_distance, - }, - ); - assert!(last.bus >= bus); - all.push((route, ((last.bus - bus) * 1000.0) as u32)); + let new = RunState { + pos: next, + bus, + total_distance, + }; + //eprintln!("{:?} -> {:?} {:?} {:?}", last.pos, new.pos, last.bus, bus); + debug_assert!((last.bus - bus) > -0.01); + all.push((new, ((last.bus - bus) * 1000.0) as u32)); } // versuche, direkt zum Bus zu gehen // Lisa trifft Bus in einem bestimmten Winkel (meist 60°) @@ -173,26 +175,26 @@ fn main() { let line_length = line.end_point().euclidean_distance(&line.start_point()); let total_distance = last.total_distance + line_length; let bus = best_bus_pos(&opt, total_distance, line.end_point()); - let mut route = state.clone(); - route.insert( - 0, - RunState { - pos: next, - bus, - total_distance, - }, - ); - all.push((route, 0)); + let new = RunState { + pos: next, + bus, + total_distance, + }; + all.push((new, 0)); } + iterations += 1; + time += Instant::now() - start; // neu gefundene Routen speichern all }, - |node| node[0].pos.x() == 0.0, + |node| node.pos.x() == 0.0, ) - .map(|x| (x.0).last().cloned()) - .unwrap() - .unwrap(); - best.reverse(); + .unwrap().0; + //best.reverse(); + + if opt.debug { + eprintln!("{}us/iteration ({} iterations)", time.as_micros() / iterations, iterations) + } // beste Lösung ausgeben eprintln!("Finale Lösung:");