Optimize path finding

This commit is contained in:
arnekeller 2019-04-07 16:30:22 +02:00
parent 9facddf889
commit 470a672afb

View File

@ -11,6 +11,7 @@ use std::f32;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::process::exit; use std::process::exit;
use std::sync::RwLock; use std::sync::RwLock;
use std::time::{self, Instant};
mod display; mod display;
mod input; mod input;
@ -26,7 +27,7 @@ type Polygon = geo::Polygon<f32>;
struct Opt { struct Opt {
/// Debug-Modus aktivieren /// Debug-Modus aktivieren
#[structopt(short = "d", long = "debug")] #[structopt(short = "d", long = "debug")]
_debug: bool, debug: bool,
/// Zwischenlösungen speichern /// Zwischenlösungen speichern
#[structopt(short = "s", long = "save")] #[structopt(short = "s", long = "save")]
_save_intermediates: bool, _save_intermediates: bool,
@ -130,11 +131,15 @@ fn main() {
"Theoretisches Maximum: {:?}", "Theoretisches Maximum: {:?}",
calc_time(distance(meeting_point, house), meeting_point.y()) calc_time(distance(meeting_point, house), meeting_point.y())
); );
let mut best = dijkstra( // Performanzmessung
&vec![start], let mut iterations = 0;
|state| { let mut time = time::Duration::from_secs(0);
let last = &state[0];
let best = dijkstra(
&start,
|last| {
let start = Instant::now();
// neue Zustände // neue Zustände
let mut all = vec![]; let mut all = vec![];
@ -142,24 +147,21 @@ fn main() {
for &next in points for &next in points
.iter() .iter()
// Ecke sollte nicht schon in Route sein // 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 // Weg zu dieser Ecke sollte kein Polygon schneiden
.filter(|&&next| none_intersect(Line::new(last.pos, next))) .filter(|&&next| none_intersect(Line::new(last.pos, next)))
{ {
// Lisa könnte zu dieser Ecke rennen // Lisa könnte zu dieser Ecke rennen
let total_distance = last.total_distance + distance(last.pos, next); let total_distance = last.total_distance + distance(last.pos, next);
let bus = best_bus_pos(&opt, total_distance, next); let bus = best_bus_pos(&opt, total_distance, next);
let mut route = state.clone(); let new = RunState {
route.insert( pos: next,
0, bus,
RunState { total_distance,
pos: next, };
bus, //eprintln!("{:?} -> {:?} {:?} {:?}", last.pos, new.pos, last.bus, bus);
total_distance, debug_assert!((last.bus - bus) > -0.01);
}, all.push((new, ((last.bus - bus) * 1000.0) as u32));
);
assert!(last.bus >= bus);
all.push((route, ((last.bus - bus) * 1000.0) as u32));
} }
// versuche, direkt zum Bus zu gehen // versuche, direkt zum Bus zu gehen
// Lisa trifft Bus in einem bestimmten Winkel (meist 60°) // 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 line_length = line.end_point().euclidean_distance(&line.start_point());
let total_distance = last.total_distance + line_length; let total_distance = last.total_distance + line_length;
let bus = best_bus_pos(&opt, total_distance, line.end_point()); let bus = best_bus_pos(&opt, total_distance, line.end_point());
let mut route = state.clone(); let new = RunState {
route.insert( pos: next,
0, bus,
RunState { total_distance,
pos: next, };
bus, all.push((new, 0));
total_distance,
},
);
all.push((route, 0));
} }
iterations += 1;
time += Instant::now() - start;
// neu gefundene Routen speichern // neu gefundene Routen speichern
all all
}, },
|node| node[0].pos.x() == 0.0, |node| node.pos.x() == 0.0,
) )
.map(|x| (x.0).last().cloned()) .unwrap().0;
.unwrap() //best.reverse();
.unwrap();
best.reverse(); if opt.debug {
eprintln!("{}us/iteration ({} iterations)", time.as_micros() / iterations, iterations)
}
// beste Lösung ausgeben // beste Lösung ausgeben
eprintln!("Finale Lösung:"); eprintln!("Finale Lösung:");