Don't store bus position
This commit is contained in:
parent
ddc323eba7
commit
103e8c309c
@ -74,6 +74,7 @@ pub(crate) fn dump_latex_code(route: &[RunState], polys: &[Polygon]) {
|
|||||||
println!("\\end{{tikzpicture}}");
|
println!("\\end{{tikzpicture}}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
pub(crate) fn dump_route(house: Point, polys: &[Polygon], route: &Vec<RunState>) {
|
pub(crate) fn dump_route(house: Point, polys: &[Polygon], route: &Vec<RunState>) {
|
||||||
let (points, lines, route1, route2_start) = gen_params(house, route);
|
let (points, lines, route1, route2_start) = gen_params(house, route);
|
||||||
print!(
|
print!(
|
||||||
@ -243,3 +244,4 @@ pub(crate) fn generate_svg(
|
|||||||
|
|
||||||
document.to_string()
|
document.to_string()
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
152
src/main.rs
152
src/main.rs
@ -23,8 +23,8 @@ struct RunState {
|
|||||||
delay: f64,
|
delay: f64,
|
||||||
/// Lisas Position
|
/// Lisas Position
|
||||||
pos: Point,
|
pos: Point,
|
||||||
/// Position des Busses
|
// Bisher zurückgelegte Strecke
|
||||||
bus: Point,
|
total_distance: f64,
|
||||||
}
|
}
|
||||||
impl cmp::Eq for RunState {}
|
impl cmp::Eq for RunState {}
|
||||||
impl cmp::Ord for RunState {
|
impl cmp::Ord for RunState {
|
||||||
@ -39,14 +39,17 @@ impl cmp::PartialOrd for RunState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// 07:00: Bus ist 15 km entfernt
|
|
||||||
let start_time = NaiveTime::from_hms(7, 0, 0);
|
|
||||||
let bus = Point::new(0.0, -15000.0);
|
|
||||||
let bus_start = bus;
|
|
||||||
// 30 km/h -> 8.3 m/s
|
// 30 km/h -> 8.3 m/s
|
||||||
let bus_speed = 30.0 / 3.6;
|
let bus_speed = 30.0 / 3.6;
|
||||||
|
let lisa_speed = 15.0 / 3.6;
|
||||||
// Zeitpunkt basierend auf Wartezeit in Sekunden berechnen
|
// Zeitpunkt basierend auf Wartezeit in Sekunden berechnen
|
||||||
let delay_to_time = |delay| start_time + Duration::seconds((delay / bus_speed) as i64);
|
let calc_time = |total_distance, y| {
|
||||||
|
NaiveTime::from_hms(7, 30, 0)
|
||||||
|
- Duration::seconds(((total_distance * 2.0 - y) / bus_speed) as i64)
|
||||||
|
};
|
||||||
|
let calc_end_time = |total_distance, y| {
|
||||||
|
calc_time(total_distance, y) + Duration::seconds((total_distance / lisa_speed) as i64)
|
||||||
|
};
|
||||||
|
|
||||||
// Input einlesen (Lisas Haus und Hindernisse)
|
// Input einlesen (Lisas Haus und Hindernisse)
|
||||||
let data = input::read_input();
|
let data = input::read_input();
|
||||||
@ -62,18 +65,22 @@ fn main() {
|
|||||||
// Startzustand: Lisa ist an ihrem Haus, Bus noch nicht losgefahren
|
// Startzustand: Lisa ist an ihrem Haus, Bus noch nicht losgefahren
|
||||||
let start = RunState {
|
let start = RunState {
|
||||||
pos: house,
|
pos: house,
|
||||||
bus: bus,
|
delay: max_possible_delay(0.0, house),
|
||||||
delay: max_possible_delay(bus, house),
|
total_distance: 0.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
eprintln!("Theoretisches Maximum: {:?}", delay_to_time(start.delay));
|
let meeting_point = Point::new(0.0, house.y() + 30.0f64.to_radians().tan() * house.x());
|
||||||
|
eprintln!(
|
||||||
|
"Theoretisches Maximum: {:?}",
|
||||||
|
calc_time(distance(meeting_point, house), meeting_point.y())
|
||||||
|
);
|
||||||
|
|
||||||
// Zustände in Max-Heap sortieren
|
// Zustände in Max-Heap sortieren
|
||||||
let mut states = BinaryHeap::new();
|
let mut states = BinaryHeap::new();
|
||||||
states.push(vec![start]);
|
states.push(vec![start]);
|
||||||
|
|
||||||
// beste Lösung speichern
|
// beste Lösung speichern
|
||||||
let mut best_delay = 0.0;
|
let mut best_delay = f64::NEG_INFINITY;
|
||||||
let mut best = vec![];
|
let mut best = vec![];
|
||||||
// Zwischenlösungen speichern
|
// Zwischenlösungen speichern
|
||||||
let save_prefix = "tmp_";
|
let save_prefix = "tmp_";
|
||||||
@ -84,6 +91,7 @@ fn main() {
|
|||||||
// besten Zustand einlesen
|
// besten Zustand einlesen
|
||||||
let state = states.pop().unwrap();
|
let state = states.pop().unwrap();
|
||||||
let last = &state[0];
|
let last = &state[0];
|
||||||
|
println!("last {:?}", last);
|
||||||
|
|
||||||
// neue Zustände
|
// neue Zustände
|
||||||
let mut all = vec![];
|
let mut all = vec![];
|
||||||
@ -98,79 +106,79 @@ fn main() {
|
|||||||
.filter(|next| none_intersect(&polys, &Line::new(last.pos, *next)))
|
.filter(|next| none_intersect(&polys, &Line::new(last.pos, *next)))
|
||||||
{
|
{
|
||||||
// Lisa könnte zu dieser Ecke rennen
|
// Lisa könnte zu dieser Ecke rennen
|
||||||
let bus_next = last.bus.translate(0.0, distance(last.pos, next) * 2.0);
|
let total_distance = last.total_distance + distance(last.pos, next);
|
||||||
let delay = max_possible_delay(bus_next, next);
|
let delay = max_possible_delay(total_distance, next);
|
||||||
if delay > best_delay {
|
if delay > best_delay {
|
||||||
let mut route = state.clone();
|
let mut route = state.clone();
|
||||||
route.insert(
|
route.insert(
|
||||||
0,
|
0,
|
||||||
RunState {
|
RunState {
|
||||||
pos: next,
|
pos: next,
|
||||||
bus: bus_next,
|
|
||||||
delay,
|
delay,
|
||||||
|
total_distance,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
all.push(route);
|
all.push(route);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// versuche, direkt zum Bus zu gehen
|
// versuche, direkt zum Bus zu gehen
|
||||||
let bus = last.bus;
|
// Lisa trifft Bus mit 60°-Winkel
|
||||||
let range = to_bus(bus, last.pos);
|
let next = Point::new(
|
||||||
if range.len() == 2 {
|
0.0,
|
||||||
// Lisa trifft Bus mit 60°-Winkel
|
last.pos.y() + 30.0f64.to_radians().tan() * last.pos.x(),
|
||||||
let next = Point::new(
|
);
|
||||||
0.0,
|
let line = Line::new(last.pos, next);
|
||||||
last.pos.y() + 30.0f64.to_radians().tan() * last.pos.x(),
|
// freier Weg?
|
||||||
);
|
if none_intersect(&polys, &line) {
|
||||||
let line = Line::new(last.pos, next);
|
let line_length = line.end_point().euclidean_distance(&line.start_point());
|
||||||
// freier Weg?
|
let total_distance = last.total_distance + line_length;
|
||||||
if none_intersect(&polys, &line) {
|
let delay = max_possible_delay(total_distance, line.end_point());
|
||||||
let delay = line.end.y
|
if delay > best_delay {
|
||||||
- bus.y() - line.end_point().euclidean_distance(&line.start_point())
|
// neue beste Wartezeit
|
||||||
* 2.0;
|
let mut route = state.clone();
|
||||||
if delay > best_delay {
|
route.insert(
|
||||||
// neue beste Wartezeit
|
0,
|
||||||
let mut route = state.clone();
|
RunState {
|
||||||
route.insert(
|
pos: next,
|
||||||
0,
|
delay,
|
||||||
RunState {
|
total_distance,
|
||||||
pos: next,
|
},
|
||||||
bus: next,
|
);
|
||||||
delay,
|
// Verbesserung anzeigen und speichern
|
||||||
},
|
eprintln!(
|
||||||
);
|
"Verbesserung: {:?} ({:?}+ Zustände verbleiben)",
|
||||||
// Verbesserung anzeigen und speichern
|
calc_time(total_distance, line.end.y),
|
||||||
eprintln!(
|
states.len()
|
||||||
"Verbesserung: {:?} ({:?}+ Zustände verbleiben)",
|
);
|
||||||
delay_to_time(delay),
|
best = route;
|
||||||
states.len()
|
best.reverse();
|
||||||
);
|
best_delay = delay;
|
||||||
best = route;
|
/*
|
||||||
best.reverse();
|
display::save_svg(
|
||||||
best_delay = delay;
|
&format!("{}{}.svg", save_prefix, save_counter),
|
||||||
display::save_svg(
|
house,
|
||||||
&format!("{}{}.svg", save_prefix, save_counter),
|
&polys,
|
||||||
house,
|
&best,
|
||||||
&polys,
|
);
|
||||||
&best,
|
*/
|
||||||
);
|
save_counter += 1;
|
||||||
save_counter += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// falls Bus überhaupt noch erreicht wird: neu gefundene Routen speichern
|
|
||||||
states.extend(all);
|
|
||||||
}
|
}
|
||||||
|
// neu gefundene Routen speichern
|
||||||
|
states.extend(all);
|
||||||
}
|
}
|
||||||
eprintln!("Finale Lösung:");
|
eprintln!("Finale Lösung:");
|
||||||
let route = best;
|
let route = best;
|
||||||
eprintln!("Startzeit: {:?}", delay_to_time(best_delay));
|
let last = route.last().unwrap();
|
||||||
|
eprintln!(
|
||||||
|
"Startzeit: {:?}",
|
||||||
|
calc_time(last.total_distance, last.pos.y())
|
||||||
|
);
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Zielzeit: {:?}",
|
"Zielzeit: {:?}",
|
||||||
delay_to_time(route.last().unwrap().bus.y() - bus_start.y())
|
calc_end_time(last.total_distance, last.pos.y())
|
||||||
);
|
);
|
||||||
eprintln!("Treffpunkt: y={:.0}", route.last().unwrap().pos.y());
|
eprintln!("Treffpunkt: y={:.0}", last.pos.y());
|
||||||
let mut length = 0.0;
|
|
||||||
let mut last = &house;
|
|
||||||
eprintln!("Route:");
|
eprintln!("Route:");
|
||||||
for s in &route {
|
for s in &route {
|
||||||
if s.pos == house {
|
if s.pos == house {
|
||||||
@ -187,11 +195,9 @@ fn main() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
eprintln!("x={:.02} y={:.02}", s.pos.x(), s.pos.y());
|
eprintln!("x={:.02} y={:.02}", s.pos.x(), s.pos.y());
|
||||||
length += last.euclidean_distance(&s.pos);
|
|
||||||
last = &s.pos;
|
|
||||||
}
|
}
|
||||||
eprintln!("Länge: {:.0}m", length);
|
eprintln!("Länge: {:.0}m", last.total_distance);
|
||||||
let seconds = length / (15.0 / 3.6);
|
let seconds = last.total_distance / (15.0 / 3.6);
|
||||||
eprintln!("Dauer: {:02.0}:{:02.0}", seconds / 60.0, seconds % 60.0);
|
eprintln!("Dauer: {:02.0}:{:02.0}", seconds / 60.0, seconds % 60.0);
|
||||||
// beste Route grafisch ausgeben
|
// beste Route grafisch ausgeben
|
||||||
display::dump_latex_code(&route, &polys);
|
display::dump_latex_code(&route, &polys);
|
||||||
@ -235,14 +241,10 @@ fn distance(a: Point, b: Point) -> f64 {
|
|||||||
((a.x() - b.x()).powi(2) + (a.y() - b.y()).powi(2)).sqrt()
|
((a.x() - b.x()).powi(2) + (a.y() - b.y()).powi(2)).sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn max_possible_delay(bus: Point, start: Point) -> f64 {
|
fn max_possible_delay(total_distance: f64, lisa: Point) -> f64 {
|
||||||
let x_l = start.x();
|
let x_l = lisa.x();
|
||||||
let y_l = start.y();
|
let y_l = lisa.y();
|
||||||
let x_b = bus.x();
|
y_l - (3.0 * x_l.powi(2)).sqrt() - total_distance * 2.0
|
||||||
assert_eq!(x_b, 0.0);
|
|
||||||
let y_b = bus.y();
|
|
||||||
|
|
||||||
y_l - (3.0 * x_l.powi(2)).sqrt() - y_b
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gehe direkt zum Bus. Gibt die Punkte zurück, bei denen Lisa nicht auf den Bus warten müsste.
|
/// Gehe direkt zum Bus. Gibt die Punkte zurück, bei denen Lisa nicht auf den Bus warten müsste.
|
||||||
|
Loading…
Reference in New Issue
Block a user