added code to generate landmarks with the greedy algorithm

This commit is contained in:
Johannes Erwerle 2022-09-15 12:42:40 +02:00
parent 076b19215a
commit 2aeb770b8f

View file

@ -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<EdgeCost>, 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<EdgeCost> = 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");
}