added current code

This commit is contained in:
Johannes Erwerle 2022-09-13 17:59:30 +02:00
parent 557558acc6
commit 41e5e9b032
39 changed files with 2431 additions and 215 deletions

160
src/alt.rs Normal file
View file

@ -0,0 +1,160 @@
use crate::gridgraph::{EdgeCost, GraphNode, GridGraph, NodeId};
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::collections::BinaryHeap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Landmark {
pub node: GraphNode,
pub distances: Vec<EdgeCost>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct LandmarkSet {
pub landmarks: Vec<Landmark>,
pub best_size: usize,
best_landmarks: Vec<usize>,
}
impl Landmark {
pub fn generate(node: GraphNode, graph: &GridGraph) -> Landmark {
let mut landmark = Landmark {
node,
distances: vec![EdgeCost::MAX; graph.nodes.len()],
};
landmark.node = node;
#[derive(Eq)]
struct DijkstraElement {
index: u32,
cost: EdgeCost,
}
impl Ord for DijkstraElement {
// inverted cmp function, such that the Max-Heap provided by Rust
// can be used as a Min-Heap
fn cmp(&self, other: &Self) -> Ordering {
other.cost.cmp(&self.cost)
}
}
impl PartialOrd for DijkstraElement {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl PartialEq for DijkstraElement {
fn eq(&self, other: &Self) -> bool {
self.cost == other.cost
}
}
let mut heap = BinaryHeap::new();
heap.push(DijkstraElement {
cost: 0,
index: landmark.node.index,
});
let mut counter = 0;
while let Some(DijkstraElement { index, cost }) = heap.pop() {
// the heap does not support "update" operations, so we
// insert elements again and if they come out of the heap but have
// been processed earlier we simply skip them.
if landmark.distances[index as usize] <= cost {
continue;
};
counter += 1;
if counter % 1000 == 0 {
println!("Finished {} nodes", counter);
}
landmark.distances[index as usize] = cost;
let edge_start = graph.edge_offsets[index as usize] as usize;
let edge_end = graph.edge_offsets[(index + 1) as usize] as usize;
for edge in graph.edges[edge_start..edge_end].iter() {
let new_cost = cost + edge.cost;
if new_cost < landmark.distances[edge.neighbor as usize] {
//println!("adding new element to heap");
heap.push(DijkstraElement {
index: edge.neighbor,
cost: new_cost,
});
}
}
}
// now the shortest paths to all reachable nodes is calculated.
landmark
}
/// calculates the lower-bounding distance estimate between the 2 nodes
/// via the landmark.
/// If one or more of the nodes are not reachable from the landmark
/// an estimate of `0` is returned.
pub fn estimate(&self, from: NodeId, to: NodeId) -> EdgeCost {
let l_to = self.distances[to];
let l_from = self.distances[from];
if l_to == EdgeCost::MAX {
0
} else {
l_to.saturating_sub(l_from)
}
}
}
impl LandmarkSet {
pub fn random_set(size: usize, best_size: usize, graph: &GridGraph) -> Self {
let mut set = LandmarkSet::default();
set.best_size = best_size;
let nodes = graph.get_random_nodes(size);
for node in nodes.into_iter() {
let landmark = Landmark::generate(*node, graph);
set.landmarks.push(landmark)
}
set
}
pub fn select_best(&mut self, from: NodeId, to: NodeId) {
let mut results = vec![];
for (index, landmark) in self.landmarks.iter().enumerate() {
results.push((index, landmark.estimate(from, to)));
}
results.sort_by_key(|k| k.1);
results.reverse();
self.best_landmarks.clear();
for result in results[..self.best_size].iter() {
self.best_landmarks.push(result.0);
}
}
pub fn estimate(&self, from: NodeId, to: NodeId) -> EdgeCost {
let mut distance = 0;
for index in &self.best_landmarks {
distance = distance.max(self.landmarks[*index].estimate(from, to));
};
if distance == 0 {
distance = EdgeCost::MAX;
}
distance
}
}