From 2aeb770b8f73c9382cef0b44b9f599d868168bc6 Mon Sep 17 00:00:00 2001 From: Johannes Erwerle Date: Thu, 15 Sep 2022 12:42:40 +0200 Subject: [PATCH] added code to generate landmarks with the greedy algorithm --- src/bin/gen_landmarks_greedy.rs | 93 +++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/bin/gen_landmarks_greedy.rs diff --git a/src/bin/gen_landmarks_greedy.rs b/src/bin/gen_landmarks_greedy.rs new file mode 100644 index 0000000..c832d66 --- /dev/null +++ b/src/bin/gen_landmarks_greedy.rs @@ -0,0 +1,93 @@ +use bincode; +use clap::Parser; +use fapra_osm_2::alt::{LandmarkSet, Landmark}; +use fapra_osm_2::gridgraph::{GridGraph, EdgeCost}; +use std::fs::File; +use std::io::prelude::*; +use std::process::exit; + +#[derive(Parser, Debug)] +#[clap(author, version, about, long_about=None)] +struct Args { + /// the FMI file to load + #[clap(short, long)] + input: String, + + /// the file to which to write the landmarks + #[clap(short, long)] + output: String, + + /// the amount of landmarks to generate + #[clap(short, long)] + amount: usize, +} + +fn main() { + let args = Args::parse(); + + let file = match File::open(args.input.clone()) { + Ok(f) => f, + Err(e) => { + println!("Error while opening file: {}", e); + exit(1); + } + }; + + let graph = GridGraph::from_fmi_file(file).unwrap(); + println!("finished loading graph from file"); + + let mut output = match File::create(args.output.clone()) { + Ok(f) => f, + Err(e) => { + println!("Error while creating the file {}: {}", args.output, e); + exit(2) + } + }; + + fn compute_next_index(costs: &mut Vec, landmark: &Landmark) -> usize { + + let mut max_index = 0; + let mut max_cost = 0; + + for (i, cost) in landmark.distances.iter().enumerate() { + if *cost < costs[i] { + costs[i] = *cost; + } + + if costs[i] > max_cost && costs[i] != EdgeCost::MAX { + max_cost = costs[i]; + max_index = i; + } + } + + max_index + } + + let initial_node = graph.get_random_node().unwrap(); + + println!("selected initial node: {:?}", initial_node); + + + let mut landmark = Landmark::generate(*initial_node, &graph); + + let mut costs: Vec = landmark.distances.clone(); + + let mut set = LandmarkSet::default(); + + let mut next = compute_next_index(&mut costs, &landmark); + set.landmarks.push(landmark); + + while set.landmarks.len() < args.amount { + let node = graph.nodes[next]; + + println!("the next node will be {:?} with a distance of {}", node, costs[node.index as usize]); + + landmark = Landmark::generate(node, &graph); + next = compute_next_index(&mut costs, &landmark); + set.landmarks.push(landmark); + } + + let encoded = bincode::serialize(&set).unwrap(); + + output.write_all(&encoded).expect("Error while writing LandmarkSet data"); +}