diff --git a/Cargo.lock b/Cargo.lock index e21b9e4..6c9c862 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2295,6 +2295,7 @@ dependencies = [ name = "graph" version = "0.1.0" dependencies = [ + "bevy_shapefile", "bincode", "itertools 0.13.0", "rayon", diff --git a/components/graph/Cargo.toml b/components/graph/Cargo.toml index 0f29533..d4ec818 100644 --- a/components/graph/Cargo.toml +++ b/components/graph/Cargo.toml @@ -6,6 +6,7 @@ version = "0.1.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +bevy_shapefile = {path = "../bevy_shapefile"} bincode = "1.3.3" itertools = "*" rayon = "1.5.1" diff --git a/components/graph/src/dijkstra_iterator.rs b/components/graph/src/dijkstra_iterator.rs index 562dacc..10860d7 100644 --- a/components/graph/src/dijkstra_iterator.rs +++ b/components/graph/src/dijkstra_iterator.rs @@ -1,21 +1,19 @@ -use crate::{ - Backward, DirectedNetworkGraph, EdgeId, Forward, NetworkData, NetworkEdge, NodeId, F32, -}; +use crate::{Backward, DirectedNetworkGraph, EdgeId, Forward, NetworkEdge, NodeId, F32}; use std::{ cmp::Reverse, collections::{BinaryHeap, HashSet}, }; -pub struct DijkstraIterator<'a, T: DijkstraDirection, D: NetworkData> { - pub network: &'a DirectedNetworkGraph, +pub struct DijkstraIterator<'a, T: DijkstraDirection> { + pub network: &'a DirectedNetworkGraph, pub distance: f32, pub visited: HashSet, pub heap: BinaryHeap>, _marker: std::marker::PhantomData, } -impl<'a, T: DijkstraDirection, D: NetworkData> DijkstraIterator<'a, T, D> { - pub fn new(network: &'a DirectedNetworkGraph, start: NodeId) -> Self { +impl<'a, T: DijkstraDirection> DijkstraIterator<'a, T> { + pub fn new(network: &'a DirectedNetworkGraph, start: NodeId) -> Self { let mut heap = BinaryHeap::new(); heap.push(Reverse((F32(0.0), start))); @@ -29,10 +27,9 @@ impl<'a, T: DijkstraDirection, D: NetworkData> DijkstraIterator<'a, T, D> { } } -impl<'a, T, D> Iterator for DijkstraIterator<'a, T, D> +impl<'a, T> Iterator for DijkstraIterator<'a, T> where T: DijkstraDirection, - D: NetworkData, { type Item = (NodeId, f32); @@ -43,7 +40,7 @@ where } for (_, edge) in T::edges(self.network, node) { let target = edge.target(); - let edge_distance = edge.distance(); + let edge_distance = edge.weight(); self.heap .push(Reverse((F32(distance + edge_distance), target))); @@ -58,15 +55,15 @@ where } pub trait DijkstraDirection { - fn edges<'a, D: NetworkData>( - network: &'a DirectedNetworkGraph, + fn edges<'a>( + network: &'a DirectedNetworkGraph, node: NodeId, ) -> impl Iterator; } impl DijkstraDirection for Forward { - fn edges<'a, D: NetworkData>( - network: &'a DirectedNetworkGraph, + fn edges<'a>( + network: &'a DirectedNetworkGraph, node: NodeId, ) -> impl Iterator { network.out_edges(node) @@ -74,8 +71,8 @@ impl DijkstraDirection for Forward { } impl DijkstraDirection for Backward { - fn edges<'a, D: NetworkData>( - network: &'a DirectedNetworkGraph, + fn edges<'a>( + network: &'a DirectedNetworkGraph, node: NodeId, ) -> impl Iterator { network.in_edges(node) diff --git a/components/graph/src/directed_graph/builder.rs b/components/graph/src/directed_adj_graph/builder.rs similarity index 91% rename from components/graph/src/directed_graph/builder.rs rename to components/graph/src/directed_adj_graph/builder.rs index adfd8a2..86baa27 100644 --- a/components/graph/src/directed_graph/builder.rs +++ b/components/graph/src/directed_adj_graph/builder.rs @@ -2,24 +2,7 @@ use crate::{DirectedNetworkGraph, NetworkData, NetworkEdge, NetworkNode, NodeId, use serde::{Deserialize, Serialize}; use std::{collections::HashMap, fmt::Debug, hash::Hash, ops::Neg}; -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] -pub enum EdgeDirection { - Forward, - Both, - Backward, -} - -impl Neg for EdgeDirection { - type Output = EdgeDirection; - fn neg(self) -> Self::Output { - match self { - EdgeDirection::Forward => EdgeDirection::Backward, - EdgeDirection::Both => EdgeDirection::Both, - EdgeDirection::Backward => EdgeDirection::Forward, - } - } -} pub trait NodeBuilder: Hash + PartialEq + Eq { type Data: Clone; diff --git a/components/graph/src/directed_graph/iterators.rs b/components/graph/src/directed_adj_graph/iterators.rs similarity index 93% rename from components/graph/src/directed_graph/iterators.rs rename to components/graph/src/directed_adj_graph/iterators.rs index e8518e9..fe697ac 100644 --- a/components/graph/src/directed_graph/iterators.rs +++ b/components/graph/src/directed_adj_graph/iterators.rs @@ -1,4 +1,4 @@ -use crate::{builder::EdgeDirection, EdgeId, NetworkEdge}; +use crate::{EdgeDirection, EdgeId, NetworkEdge}; use std::{ops::Range, slice::Iter}; pub struct EdgeIterator<'a> { diff --git a/components/graph/src/directed_graph/mod.rs b/components/graph/src/directed_adj_graph/mod.rs similarity index 82% rename from components/graph/src/directed_graph/mod.rs rename to components/graph/src/directed_adj_graph/mod.rs index ad8b332..6cf9f09 100644 --- a/components/graph/src/directed_graph/mod.rs +++ b/components/graph/src/directed_adj_graph/mod.rs @@ -1,13 +1,30 @@ -use self::{builder::EdgeDirection, iterators::EdgeIterator}; +use self::iterators::EdgeIterator; use crate::{ dijkstra_iterator::DijkstraIterator, Backward, EdgeId, Forward, Neighbourhood, NodeId, }; -pub use node_data::NetworkData; use serde::{Deserialize, Serialize}; +use std::ops::Neg; -pub mod builder; pub mod iterators; -pub mod node_data; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] +pub enum EdgeDirection { + Forward, + Both, + Backward, +} + +impl Neg for EdgeDirection { + type Output = EdgeDirection; + + fn neg(self) -> Self::Output { + match self { + EdgeDirection::Forward => EdgeDirection::Backward, + EdgeDirection::Both => EdgeDirection::Both, + EdgeDirection::Backward => EdgeDirection::Forward, + } + } +} /// A node in the graph. #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] @@ -58,7 +75,7 @@ impl NetworkEdge { self.target_node.into() } - pub fn distance(&self) -> f32 { + pub fn weight(&self) -> f32 { self.edge_weight } } @@ -67,29 +84,20 @@ impl NetworkEdge { /// It's an adjacency list representation of a graph. /// The graph is immutable. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct DirectedNetworkGraph { - pub data: D, +pub struct DirectedNetworkGraph { nodes: Vec, edges: Vec, } -impl DirectedNetworkGraph { - pub fn new(nodes: Vec, edges: Vec, data: D) -> Self { - Self { data, nodes, edges } +impl DirectedNetworkGraph { + pub fn new(nodes: Vec, edges: Vec) -> Self { + Self { nodes, edges } } pub fn node(&self, node: NodeId) -> &NetworkNode { &self.nodes[node.0 as usize] } - pub fn edge_data(&self, edge: EdgeId) -> &D::EdgeData { - self.data.edge_data(edge) - } - - pub fn node_data(&self, node: NodeId) -> &D::NodeData { - self.data.node_data(node) - } - pub fn nodes(&self) -> &Vec { &self.nodes } @@ -133,11 +141,11 @@ impl DirectedNetworkGraph { self.create_iterator_raw(node, EdgeDirection::Backward) } - pub fn forward_iterator(&self, node: NodeId) -> DijkstraIterator<'_, Forward, D> { + pub fn forward_iterator(&self, node: NodeId) -> DijkstraIterator<'_, Forward> { DijkstraIterator::new(self, node) } - pub fn backward_iterator(&self, node: NodeId) -> DijkstraIterator<'_, Backward, D> { + pub fn backward_iterator(&self, node: NodeId) -> DijkstraIterator<'_, Backward> { DijkstraIterator::new(self, node) } diff --git a/components/graph/src/directed_adj_graph/node_data.rs b/components/graph/src/directed_adj_graph/node_data.rs new file mode 100644 index 0000000..035c555 --- /dev/null +++ b/components/graph/src/directed_adj_graph/node_data.rs @@ -0,0 +1,94 @@ +use crate::{EdgeId, NodeId, ShortcutState}; + +#[derive(Debug)] +pub struct DefaultNetworkData { + nodes: Vec>, + edges: Vec>, + shortcuts: Vec>>, +} + +impl Default for DefaultNetworkData { + fn default() -> Self { + DefaultNetworkData { + nodes: Vec::new(), + edges: Vec::new(), + shortcuts: Vec::new(), + } + } +} + +pub trait NetworkData: Send + Sync + Default { + type NodeData; + type EdgeData; + fn node_data(&self, node: NodeId) -> &Self::NodeData; + fn edge_data(&self, edge: EdgeId) -> &Self::EdgeData; + fn edge_road_id(&self, edge: EdgeId) -> ShortcutState; + + fn with_size(node_size: usize, edge_size: usize) -> Self; + fn add_node(&mut self, node: NodeId, data: Self::NodeData); + fn add_edge(&mut self, edge: EdgeId, data: Self::EdgeData, road_id: ShortcutState); +} + +impl NetworkData for () { + type NodeData = (); + type EdgeData = (); + + fn node_data(&self, _: NodeId) -> &Self::NodeData { + &() + } + + fn edge_data(&self, _: EdgeId) -> &Self::EdgeData { + &() + } + + fn edge_road_id(&self, edge: EdgeId) -> ShortcutState { + ShortcutState::Single(edge) + } + + fn add_node(&mut self, _: NodeId, _: Self::NodeData) {} + + fn add_edge(&mut self, _: EdgeId, _: Self::EdgeData, _: ShortcutState) {} + + fn with_size(_: usize, _: usize) -> Self { + () + } +} + +impl NetworkData for DefaultNetworkData +where + N: Send + Sync + Clone, + E: Send + Sync + Clone, +{ + type NodeData = N; + + type EdgeData = E; + + fn node_data(&self, node: NodeId) -> &Self::NodeData { + self.nodes[node.0 as usize].as_ref().unwrap() + } + + fn edge_data(&self, edge: EdgeId) -> &Self::EdgeData { + self.edges[edge.0 as usize].as_ref().unwrap() + } + + fn edge_road_id(&self, edge: EdgeId) -> ShortcutState { + self.shortcuts[edge.0 as usize].clone().unwrap() + } + + fn with_size(node_size: usize, edge_size: usize) -> Self { + DefaultNetworkData { + nodes: vec![None; node_size], + edges: vec![None; edge_size], + shortcuts: vec![None; edge_size], + } + } + + fn add_node(&mut self, node: NodeId, data: Self::NodeData) { + self.nodes[node.0 as usize] = Some(data); + } + + fn add_edge(&mut self, edge: EdgeId, data: Self::EdgeData, road_id: ShortcutState) { + self.edges[edge.0 as usize] = Some(data); + self.shortcuts[edge.0 as usize] = Some(road_id); + } +} diff --git a/components/graph/src/directed_graph/node_data.rs b/components/graph/src/directed_graph/node_data.rs deleted file mode 100644 index 6676fbf..0000000 --- a/components/graph/src/directed_graph/node_data.rs +++ /dev/null @@ -1,38 +0,0 @@ -use crate::{EdgeId, NodeId, ShortcutState}; - -pub trait NetworkData: Send + Sync + Default { - type NodeData; - type EdgeData; - fn node_data(&self, node: NodeId) -> &Self::NodeData; - fn edge_data(&self, edge: EdgeId) -> &Self::EdgeData; - fn edge_road_id(&self, edge: EdgeId) -> ShortcutState; - - fn with_size(node_size: usize, edge_size: usize) -> Self; - fn add_node(&mut self, node: NodeId, data: Self::NodeData); - fn add_edge(&mut self, edge: EdgeId, data: Self::EdgeData, road_id: ShortcutState); -} - -impl NetworkData for () { - type NodeData = (); - type EdgeData = (); - - fn node_data(&self, _: NodeId) -> &Self::NodeData { - &() - } - - fn edge_data(&self, _: EdgeId) -> &Self::EdgeData { - &() - } - - fn edge_road_id(&self, edge: EdgeId) -> ShortcutState { - ShortcutState::Single(edge.0 as usize) - } - - fn add_node(&mut self, _: NodeId, _: Self::NodeData) {} - - fn add_edge(&mut self, _: EdgeId, _: Self::EdgeData, _: ShortcutState) {} - - fn with_size(_: usize, _: usize) -> Self { - () - } -} diff --git a/components/graph/src/directed_map_graph/mod.rs b/components/graph/src/directed_map_graph/mod.rs new file mode 100644 index 0000000..ac89d6e --- /dev/null +++ b/components/graph/src/directed_map_graph/mod.rs @@ -0,0 +1,514 @@ +use itertools::Itertools; +use rayon::prelude::*; + +use crate::{ + DirectedNetworkGraph, EdgeDirection, EdgeId, NetworkEdge, NetworkNode, NodeId, ShortcutState, +}; +use std::collections::HashMap; + +#[derive(Clone, PartialEq, Debug)] +pub struct Edge { + target: NodeId, + source: NodeId, + weight: f32, +} + +#[derive(Clone, Default, Debug, PartialEq)] +pub struct DirectedMapGraph { + out_edges: HashMap>, + in_edges: HashMap>, + edge_count: usize, +} + +impl DirectedMapGraph { + pub fn new() -> Self { + Self { + ..Default::default() + } + } + + pub fn nodes(&self) -> Vec { + self.out_edges.keys().cloned().collect() + } + + pub fn out_edges(&self, node: NodeId) -> &Vec { + &self.out_edges[&node] + } + + pub fn add_node(&mut self) -> NodeId { + let index = NodeId(self.out_edges.len() as u32); + self.out_edges.insert(index, Vec::new()); + self.in_edges.insert(index, Vec::new()); + + index + } + + pub fn add_edge(&mut self, source: NodeId, target: NodeId, weight: f32) { + let id = EdgeId(self.edge_count as u32); + + self.out_edges.get_mut(&source).unwrap().push(Edge { + target, + source, + weight, + }); + self.in_edges.get_mut(&target).unwrap().push(Edge { + target, + source, + weight, + }); + self.edge_count += 1; + } +} + +impl From for DirectedMapGraph { + fn from(graph: DirectedNetworkGraph) -> Self { + let mut new_graph = Self::new(); + for _ in 0..graph.nodes().len() { + new_graph.add_node(); + } + for (id, _) in graph.nodes().into_iter().enumerate() { + for (_, edge) in graph.out_edges(NodeId(id as u32)) { + new_graph.add_edge(NodeId(id as u32), edge.target(), edge.weight()); + } + } + + new_graph + } +} + +impl From for DirectedNetworkGraph { + fn from(mut value: DirectedMapGraph) -> Self { + let mut nodes = Vec::with_capacity(value.out_edges.len()); + let mut edges = Vec::with_capacity(value.edge_count); + + for node_id in (0..value.out_edges.len()).map(|i| NodeId(i as u32)) { + let out_edges = value.out_edges.remove(&node_id).unwrap(); + let in_edges = value.in_edges.remove(&node_id).unwrap(); + + let start_edge_index = edges.len() as u32; + + let (out_edges, overlaping_edges, in_edges) = collect_edges(in_edges, out_edges); + + edges.extend(extend_edges( + start_edge_index, + out_edges, + EdgeDirection::Forward, + |e| e.target, + )); + edges.extend(extend_edges( + edges.len() as u32, + overlaping_edges, + EdgeDirection::Both, + |e| e.target, + )); + edges.extend(extend_edges( + edges.len() as u32, + in_edges, + EdgeDirection::Backward, + |e| e.source, + )); + + let last_edge_index = edges.len() as u32; + + nodes.push(NetworkNode::new(start_edge_index, last_edge_index)); + } + + DirectedNetworkGraph::new(nodes, edges) + } +} + +fn collect_edges( + mut in_edges: Vec, + mut out_edges: Vec, +) -> (Vec, Vec, Vec) { + // Find overlapping edges + let overlaping_edges = out_edges + .iter() + .filter(|e| { + in_edges + .iter() + .any(|ie| ie.source == e.target && ie.target == e.source) + }) + .cloned() + .collect::>(); + + // Remove overlapping edges from in_edges + in_edges.retain(|ie| { + !overlaping_edges + .iter() + .any(|e| e.source == ie.target && e.target == ie.source) + }); + + // Remove overlapping edges from out_edges + out_edges.retain(|e| { + !overlaping_edges + .iter() + .any(|ie| ie.source == e.source && ie.target == e.target) + }); + + (out_edges, overlaping_edges, in_edges) +} + +fn extend_edges( + offset: u32, + edges: Vec, + direction: EdgeDirection, + target_node: F, +) -> impl Iterator +where + F: Fn(&Edge) -> NodeId, +{ + edges.into_iter().enumerate().map(move |(i, e)| { + NetworkEdge::new(offset + i as u32, target_node(&e), e.weight, direction) + }) +} + +pub trait EdgeBuilder { + fn source(&self) -> NodeId; + fn target(&self) -> NodeId; + fn weight(&self) -> f32; + fn road_id(&self) -> ShortcutState; +} + +impl From> for DirectedMapGraph +where + E: EdgeBuilder, +{ + fn from(edges: Vec) -> Self { + let mut graph = DirectedMapGraph::new(); + let nodes = edges + .iter() + .map(|edge| [edge.source(), edge.target()]) + .flatten() + .sorted_by_key(|n| n.0) + .collect::>(); + + let convert = nodes + .into_iter() + .map(|n| (n, graph.add_node())) + .collect::>(); + + for edge in edges { + graph.add_edge( + convert[&edge.source()], + convert[&edge.target()], + edge.weight(), + ); + } + + graph + } +} + +impl FromIterator for DirectedMapGraph +where + E: EdgeBuilder, +{ + fn from_iter>(iter: T) -> Self { + let edges = iter.into_iter().collect::>(); + edges.into() + } +} + +impl FromParallelIterator for DirectedMapGraph +where + E: EdgeBuilder + Send + Sync, +{ + fn from_par_iter(par_iter: I) -> Self + where + I: rayon::iter::IntoParallelIterator, + { + let edges = par_iter.into_par_iter().collect::>(); + edges.into() + } +} + +#[cfg(test)] +mod tests { + + use super::*; + + fn build_graph() -> DirectedMapGraph { + let mut graph = DirectedMapGraph::new(); + + for _ in 0..5 { + graph.add_node(); + } + + graph.add_edge(NodeId(0), NodeId(1), 1.0); + graph.add_edge(NodeId(0), NodeId(2), 2.0); + graph.add_edge(NodeId(0), NodeId(3), 3.0); + graph.add_edge(NodeId(1), NodeId(4), 3.0); + graph.add_edge(NodeId(2), NodeId(4), 4.0); + graph.add_edge(NodeId(4), NodeId(3), 4.0); + graph.add_edge(NodeId(4), NodeId(1), 3.0); + + graph + } + + #[test] + fn test_directed_map_graph() { + let graph = build_graph(); + + assert_eq!(graph.out_edges[&NodeId(0)].len(), 3); + assert_eq!(graph.out_edges[&NodeId(1)].len(), 1); + assert_eq!(graph.out_edges[&NodeId(2)].len(), 1); + assert_eq!(graph.out_edges[&NodeId(3)].len(), 0); + assert_eq!(graph.out_edges[&NodeId(4)].len(), 2); + + assert_eq!(graph.in_edges[&NodeId(0)].len(), 0); + assert_eq!(graph.in_edges[&NodeId(1)].len(), 2); + assert_eq!(graph.in_edges[&NodeId(2)].len(), 1); + assert_eq!(graph.in_edges[&NodeId(3)].len(), 2); + assert_eq!(graph.in_edges[&NodeId(4)].len(), 2); + } + + #[test] + fn test_directed_map_graph_conversion() { + let graph = build_graph(); + // println!("{:?}", graph); + let network_graph: DirectedNetworkGraph = graph.clone().into(); + + let out_edges = [ + network_graph.out_edges(NodeId(0)).collect::>(), + network_graph.out_edges(NodeId(1)).collect::>(), + network_graph.out_edges(NodeId(2)).collect::>(), + network_graph.out_edges(NodeId(3)).collect::>(), + network_graph.out_edges(NodeId(4)).collect::>(), + ] + .map(|s| s.into_iter().map(|s| s.1.clone()).collect::>()); + + let in_edges = [ + network_graph.in_edges(NodeId(0)).collect::>(), + network_graph.in_edges(NodeId(1)).collect::>(), + network_graph.in_edges(NodeId(2)).collect::>(), + network_graph.in_edges(NodeId(3)).collect::>(), + network_graph.in_edges(NodeId(4)).collect::>(), + ] + .map(|s| s.into_iter().map(|s| s.1.clone()).collect::>()); + + assert_eq!(out_edges[0].len(), 3); + assert_eq!(out_edges[1].len(), 1); + assert_eq!(out_edges[2].len(), 1); + assert_eq!(out_edges[3].len(), 0); + assert_eq!(out_edges[4].len(), 2); + + assert_eq!(in_edges[0].len(), 0); + assert_eq!(in_edges[1].len(), 2); + assert_eq!(in_edges[2].len(), 1); + assert_eq!(in_edges[3].len(), 2); + assert_eq!(in_edges[4].len(), 2); + + let expected_out = [ + vec![ + NetworkEdge::new(0, NodeId(1), 1.0, EdgeDirection::Forward), + NetworkEdge::new(1, NodeId(2), 2.0, EdgeDirection::Forward), + NetworkEdge::new(2, NodeId(3), 3.0, EdgeDirection::Forward), + ], + vec![NetworkEdge::new(3, NodeId(4), 3.0, EdgeDirection::Both)], + vec![NetworkEdge::new(5, NodeId(4), 4.0, EdgeDirection::Forward)], + vec![], + vec![ + NetworkEdge::new(9, NodeId(3), 4.0, EdgeDirection::Forward), + NetworkEdge::new(10, NodeId(1), 3.0, EdgeDirection::Both), + ], + ]; + + let expected_in = [ + vec![], + vec![ + NetworkEdge::new(3, NodeId(4), 3.0, EdgeDirection::Both), + NetworkEdge::new(4, NodeId(0), 1.0, EdgeDirection::Backward), + ], + vec![NetworkEdge::new(6, NodeId(0), 2.0, EdgeDirection::Backward)], + vec![ + NetworkEdge::new(7, NodeId(0), 3.0, EdgeDirection::Backward), + NetworkEdge::new(8, NodeId(4), 4.0, EdgeDirection::Backward), + ], + vec![ + NetworkEdge::new(10, NodeId(1), 3.0, EdgeDirection::Both), + NetworkEdge::new(11, NodeId(2), 4.0, EdgeDirection::Backward), + ], + ]; + + for i in 0..5 { + assert_eq!(expected_out[i], out_edges[i], "out node: {}", i); + } + + for i in 0..5 { + assert_eq!(expected_in[i], in_edges[i], "in node: {}", i); + } + } + + #[test] + fn test_directed_map_graph_conversion_and_back() { + let graph = build_graph(); + // println!("{:?}", graph); + let network_graph: DirectedNetworkGraph = graph.clone().into(); + let back_graph: DirectedMapGraph = network_graph.into(); + + assert_eq!(graph, back_graph); + } + + #[test] + fn test_collect_edges_empty() { + let in_edges = vec![]; + let out_edges = vec![]; + let (a, b, c) = super::collect_edges(in_edges, out_edges); + + assert_eq!(a, vec![]); + assert_eq!(b, vec![]); + assert_eq!(c, vec![]); + } + + #[test] + fn test_collect_edges_in_only() { + let in_edges = vec![ + Edge { + source: NodeId(1), + target: NodeId(0), + weight: 1.0, + }, + Edge { + source: NodeId(2), + target: NodeId(0), + weight: 1.0, + }, + Edge { + source: NodeId(3), + target: NodeId(0), + weight: 1.0, + }, + ]; + let out_edges = vec![]; + let (a, b, c) = super::collect_edges(in_edges.clone(), out_edges); + + assert_eq!(a, vec![]); + assert_eq!(b, vec![]); + assert_eq!(c, in_edges); + } + + #[test] + fn test_collect_edges_out_only() { + let in_edges = vec![]; + let out_edges = vec![ + Edge { + source: NodeId(0), + target: NodeId(1), + weight: 1.0, + }, + Edge { + source: NodeId(0), + target: NodeId(2), + weight: 1.0, + }, + Edge { + source: NodeId(0), + target: NodeId(3), + weight: 1.0, + }, + ]; + let (a, b, c) = super::collect_edges(in_edges, out_edges.clone()); + + assert_eq!(a, out_edges); + assert_eq!(b, vec![]); + assert_eq!(c, vec![]); + } + + #[test] + fn test_collect_edges_all_overlapping() { + let in_edges = vec![ + Edge { + source: NodeId(1), + target: NodeId(0), + weight: 1.0, + }, + Edge { + source: NodeId(2), + target: NodeId(0), + weight: 1.0, + }, + Edge { + source: NodeId(3), + target: NodeId(0), + weight: 1.0, + }, + ]; + let out_edges = vec![ + Edge { + source: NodeId(0), + target: NodeId(1), + weight: 1.0, + }, + Edge { + source: NodeId(0), + target: NodeId(2), + weight: 1.0, + }, + Edge { + source: NodeId(0), + target: NodeId(3), + weight: 1.0, + }, + ]; + let (a, b, c) = super::collect_edges(in_edges, out_edges.clone()); + + assert_eq!(a, vec![]); + assert_eq!(b, out_edges); + assert_eq!(c, vec![]); + } + + #[test] + fn test_collecte_edges() { + let in_edges = vec![ + Edge { + source: NodeId(1), + target: NodeId(0), + weight: 1.0, + }, + Edge { + source: NodeId(2), + target: NodeId(0), + weight: 1.0, + }, + ]; + let out_edges = vec![ + Edge { + source: NodeId(0), + target: NodeId(2), + weight: 1.0, + }, + Edge { + source: NodeId(0), + target: NodeId(3), + weight: 1.0, + }, + ]; + let (a, b, c) = super::collect_edges(in_edges, out_edges); + + assert_eq!( + a, + vec![Edge { + source: NodeId(0), + target: NodeId(3), + weight: 1.0, + }] + ); + assert_eq!( + b, + vec![Edge { + source: NodeId(0), + target: NodeId(2), + weight: 1.0, + }] + ); + assert_eq!( + c, + vec![Edge { + source: NodeId(1), + target: NodeId(0), + weight: 1.0, + }] + ); + } +} diff --git a/components/graph/src/highway_network/iterators.rs b/components/graph/src/highway_network/iterators.rs index 41a6448..62f011e 100644 --- a/components/graph/src/highway_network/iterators.rs +++ b/components/graph/src/highway_network/iterators.rs @@ -1,5 +1,5 @@ use super::{HighwayNetwork, NetworkEdge}; -use crate::{builder::EdgeDirection, EdgeId, NodeId}; +use crate::{EdgeDirection, EdgeId, NodeId}; use core::slice::Iter; use std::ops::Range; diff --git a/components/graph/src/highway_network/mod.rs b/components/graph/src/highway_network/mod.rs index c26155f..2f8872e 100644 --- a/components/graph/src/highway_network/mod.rs +++ b/components/graph/src/highway_network/mod.rs @@ -1,11 +1,8 @@ -use std::collections::HashMap; - +use self::iterators::EdgeIterator; +use crate::{DirectedNetworkGraph, EdgeDirection, NodeId}; use itertools::Itertools; use serde::{Deserialize, Serialize}; - -use crate::{builder::EdgeDirection, DirectedNetworkGraph, NodeId}; - -use self::iterators::EdgeIterator; +use std::collections::HashMap; mod iterators; diff --git a/components/graph/src/lib.rs b/components/graph/src/lib.rs index 4718204..d86b2cf 100644 --- a/components/graph/src/lib.rs +++ b/components/graph/src/lib.rs @@ -6,11 +6,12 @@ use std::ops::Deref; -pub use directed_graph::*; +pub use directed_adj_graph::*; pub use neighbourhood::*; /// Tja -pub mod directed_graph; +pub mod directed_adj_graph; +pub mod directed_map_graph; pub mod highway_network; pub mod neighbourhood; @@ -102,23 +103,26 @@ impl From> for Vec { macro_rules! create_network { ($s:literal..$e:literal, $($a:literal => $b:literal; $c: expr),+) => { { - use $crate::builder::DefaultEdgeBuilder; - use $crate::builder::DirectedNetworkBuilder; - let mut builder = DirectedNetworkBuilder::::new(); + use $crate::directed_map_graph::{DirectedMapGraph, Edge}; + use $crate::{NodeId, ShortcutState}; + use $crate::directed_adj_graph::DirectedNetworkGraph; + // use $crate::builder::DefaultEdgeBuilder; + // use $crate::::DirectedNetworkBuilder; + // let mut builder = DirectedNetworkBuilder::::new(); + let mut builder = DirectedMapGraph::new(); for x in $s..=$e { - builder.add_node(x); + builder.add_node(); } $({ - let source = builder.add_node($a); - let target = builder.add_node($b); - - builder.add_edge(DefaultEdgeBuilder::forward(source, target, 0, $c)); + let source = NodeId($a as u32); + let target = NodeId($b as u32); + builder.add_edge(source, target, $c); })+ - builder.build::<()>() + DirectedNetworkGraph::from(builder) } }; } diff --git a/components/graph/src/neighbourhood.rs b/components/graph/src/neighbourhood.rs index af25e49..0f24126 100644 --- a/components/graph/src/neighbourhood.rs +++ b/components/graph/src/neighbourhood.rs @@ -1,4 +1,4 @@ -use crate::{Backward, DirectedNetworkGraph, Forward, NetworkData, NodeId}; +use crate::{Backward, DirectedNetworkGraph, Forward, NodeId}; use rayon::prelude::*; pub type ForwardNeighbourhood = Neighbourhood; @@ -22,22 +22,19 @@ where self.radius[node.0 as usize] } - pub fn from_network(size: usize, network: &DirectedNetworkGraph) -> Self { + pub fn from_network(size: usize, network: &DirectedNetworkGraph) -> Self { T::from_network(size, network) } } pub trait NeighbourhoodDirection { - fn find_neighbourhood_radius( + fn find_neighbourhood_radius( node: NodeId, size: usize, - network: &DirectedNetworkGraph, + network: &DirectedNetworkGraph, ) -> Option; - fn from_network( - size: usize, - network: &DirectedNetworkGraph, - ) -> Neighbourhood + fn from_network(size: usize, network: &DirectedNetworkGraph) -> Neighbourhood where Self: Sized, { @@ -58,10 +55,10 @@ pub trait NeighbourhoodDirection { } impl NeighbourhoodDirection for Forward { - fn find_neighbourhood_radius( + fn find_neighbourhood_radius( node: NodeId, size: usize, - network: &DirectedNetworkGraph, + network: &DirectedNetworkGraph, ) -> Option { network .forward_iterator(node) @@ -72,10 +69,10 @@ impl NeighbourhoodDirection for Forward { } impl NeighbourhoodDirection for Backward { - fn find_neighbourhood_radius( + fn find_neighbourhood_radius( node: NodeId, size: usize, - network: &DirectedNetworkGraph, + network: &DirectedNetworkGraph, ) -> Option { network .backward_iterator(node) diff --git a/components/graph/tests/builder.rs b/components/graph/tests/builder.rs deleted file mode 100644 index 7b68d3b..0000000 --- a/components/graph/tests/builder.rs +++ /dev/null @@ -1,75 +0,0 @@ -use std::ops::Neg; - -use graph::{ - builder::{DefaultEdgeBuilder, DirectedNetworkBuilder, EdgeDirection}, - DirectedNetworkGraph, NetworkEdge, NetworkNode, -}; - -// https://www.baeldung.com/wp-content/uploads/2017/01/initial-graph.png -fn create_ref_network_1() -> DirectedNetworkGraph<()> { - let nodes = vec![ - NetworkNode::new(0, 2), - NetworkNode::new(2, 5), - NetworkNode::new(5, 7), - NetworkNode::new(7, 10), - NetworkNode::new(10, 13), - NetworkNode::new(13, 16), - ]; - let edges = vec![ - NetworkEdge::new(0, 1u32.into(), 10.0, EdgeDirection::Forward), // A -> B - NetworkEdge::new(1, 2u32.into(), 15.0, EdgeDirection::Forward), // A -> C - NetworkEdge::new(2, 3u32.into(), 12.0, EdgeDirection::Forward), // B -> D - NetworkEdge::new(3, 5u32.into(), 15.0, EdgeDirection::Forward), // B -> F - NetworkEdge::new(4, 0u32.into(), 10.0, EdgeDirection::Backward), // A <- B - NetworkEdge::new(5, 4u32.into(), 10.0, EdgeDirection::Forward), // C -> E - NetworkEdge::new(6, 0u32.into(), 15.0, EdgeDirection::Backward), // A <- C - NetworkEdge::new(7, 4u32.into(), 2.0, EdgeDirection::Forward), // D -> E - NetworkEdge::new(8, 5u32.into(), 1.0, EdgeDirection::Forward), // D -> F - NetworkEdge::new(9, 1u32.into(), 12.0, EdgeDirection::Backward), // B <- D - NetworkEdge::new(10, 2u32.into(), 10.0, EdgeDirection::Backward), // C <- E - NetworkEdge::new(11, 3u32.into(), 2.0, EdgeDirection::Backward), // D <- E - NetworkEdge::new(12, 5u32.into(), 5.0, EdgeDirection::Backward), // F <- E - NetworkEdge::new(13, 4u32.into(), 5.0, EdgeDirection::Forward), // F -> E - NetworkEdge::new(14, 1u32.into(), 15.0, EdgeDirection::Backward), // B <- F - NetworkEdge::new(15, 3u32.into(), 1.0, EdgeDirection::Backward), // D <- F - ]; - - DirectedNetworkGraph::new(nodes, edges, ()) -} - -fn create_network() -> DirectedNetworkGraph<()> { - let mut builder = DirectedNetworkBuilder::new(); - - let na = builder.add_node(0); - let nb = builder.add_node(1); - let nc = builder.add_node(2); - let nd = builder.add_node(3); - let ne = builder.add_node(4); - let nf = builder.add_node(5); - - builder.add_edge(DefaultEdgeBuilder::forward(na, nb, 0, 10.0)); - builder.add_edge(DefaultEdgeBuilder::forward(nb, nd, 0, 12.0)); - builder.add_edge(DefaultEdgeBuilder::forward(nd, ne, 0, 2.0)); - builder.add_edge(DefaultEdgeBuilder::forward(na, nc, 0, 15.0)); - builder.add_edge(DefaultEdgeBuilder::forward(nc, ne, 0, 10.0)); - builder.add_edge(DefaultEdgeBuilder::forward(nf, ne, 0, 5.0)); - builder.add_edge(DefaultEdgeBuilder::forward(nb, nf, 0, 15.0)); - builder.add_edge(DefaultEdgeBuilder::forward(nd, nf, 0, 1.0)); - - builder.build() -} - -#[test] -fn builder_test() { - let n1 = create_ref_network_1(); - let n2 = create_network(); - - assert_eq!(n1, n2); -} - -#[test] -fn reverse() { - assert_eq!(EdgeDirection::Backward.neg(), EdgeDirection::Forward); - assert_eq!(EdgeDirection::Forward.neg(), EdgeDirection::Backward); - assert_eq!(EdgeDirection::Both.neg(), EdgeDirection::Both); -} diff --git a/components/graph/tests/edge_id.rs b/components/graph/tests/edge_id.rs index d213cac..1904e8d 100644 --- a/components/graph/tests/edge_id.rs +++ b/components/graph/tests/edge_id.rs @@ -1,4 +1,6 @@ -use graph::EdgeId; +use std::ops::Neg; + +use graph::{EdgeDirection, EdgeId}; #[test] fn edge_from_usize_test() { @@ -18,3 +20,10 @@ fn shortcut_into() { assert_eq!(c, vec![1]); assert_eq!(d, vec![1, 2, 3]); } + +#[test] +fn reverse() { + assert_eq!(EdgeDirection::Backward.neg(), EdgeDirection::Forward); + assert_eq!(EdgeDirection::Forward.neg(), EdgeDirection::Backward); + assert_eq!(EdgeDirection::Both.neg(), EdgeDirection::Both); +} \ No newline at end of file diff --git a/components/highway/src/generation/dijkstra.rs b/components/highway/src/generation/dijkstra.rs index effadbe..00a9c4a 100644 --- a/components/highway/src/generation/dijkstra.rs +++ b/components/highway/src/generation/dijkstra.rs @@ -66,14 +66,14 @@ pub fn create_directed_acyclic_graph( for (id, child_edge) in network.out_edges(entry.state.current) { let child = child_edge.target(); - let next_distance = entry.state.distance + child_edge.distance(); + let next_distance = entry.state.distance + child_edge.weight(); heap.push(DijkstraNodeState { current: child, distance: next_distance, parent: ParentEntry { parent: entry.state.current, - parent_edge_distance: child_edge.distance(), + parent_edge_distance: child_edge.weight(), parent_edge: id.into(), active, }, @@ -142,11 +142,11 @@ fn initialize_heap( for (id, edge) in network.out_edges(s0) { // assert!(s0 != edge.target()); heap.push(DijkstraNodeState { - distance: edge.distance(), + distance: edge.weight(), current: edge.target(), parent: ParentEntry { parent: s0, - parent_edge_distance: edge.distance(), + parent_edge_distance: edge.weight(), parent_edge: id.into(), active: true, }, @@ -190,16 +190,13 @@ fn reference_distance( #[cfg(test)] mod tests { - + use super::{create_directed_acyclic_graph, ComputedState}; + use crate::generation::dijkstra::collect_next_level_edges; use graph::{ - builder::EdgeDirection, create_network, DirectedNetworkGraph, NetworkEdge, NetworkNode, - NodeId, + create_network, DirectedNetworkGraph, EdgeDirection, NetworkEdge, NetworkNode, NodeId, }; use std::collections::HashSet; - use crate::generation::dijkstra::collect_next_level_edges; - - use super::{create_directed_acyclic_graph, ComputedState}; // https://www.baeldung.com/wp-content/uploads/2017/01/initial-graph.png pub fn create_ref_network_1() -> DirectedNetworkGraph<()> { let nodes = vec![ diff --git a/components/highway/src/generation/intermediate_network.rs b/components/highway/src/generation/intermediate_network.rs index 0778161..e0cc746 100644 --- a/components/highway/src/generation/intermediate_network.rs +++ b/components/highway/src/generation/intermediate_network.rs @@ -1,13 +1,21 @@ +// use graph::{ +// DirectedNetworkGraph, EdgeId, NetworkData, NodeId, ShortcutState, +// }; +// use rayon::iter::{FromParallelIterator, ParallelIterator}; +// use serde::{Deserialize, Serialize}; +// use std::collections::HashMap; + +// #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +// pub struct IntermediateNode(pub NodeId); + use graph::{ - builder::{DirectedNetworkBuilder, EdgeBuilder, EdgeDirection, NodeBuilder}, - DirectedNetworkGraph, EdgeId, NetworkData, NodeId, ShortcutState, + directed_map_graph::{DirectedMapGraph, EdgeBuilder}, + node_data::DefaultNetworkData, + EdgeDirection, NodeId, ShortcutState, }; -use rayon::iter::{FromParallelIterator, ParallelIterator}; -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; -#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct IntermediateNode(pub NodeId); +pub type IntermediateData = DefaultNetworkData<(), ShortcutState>; +pub type IntermediateNetwork = DirectedMapGraph; #[derive(Debug, Clone)] pub struct IntermediateEdge { @@ -19,46 +27,6 @@ pub struct IntermediateEdge { weight: f32, } -impl NodeBuilder for IntermediateNode { - type Data = NodeId; - - fn id(&self) -> u32 { - self.0 .0 - } - - fn data(&self) -> Self::Data { - self.0 - } -} - -impl EdgeBuilder for IntermediateEdge { - type Data = ShortcutState; // Points to road_id - - fn data(&self) -> Self::Data { - self.data.clone() - } - - fn source(&self) -> NodeId { - self.source - } - - fn target(&self) -> NodeId { - self.target - } - - fn weight(&self) -> f32 { - self.weight - } - - fn direction(&self) -> EdgeDirection { - self.direction - } - - fn road_id(&self) -> ShortcutState { - self.road_id.clone() - } -} - impl IntermediateEdge { pub fn new( source: NodeId, @@ -79,205 +47,269 @@ impl IntermediateEdge { } } -#[derive(Debug, Default)] -pub(crate) struct IntermediateNetwork { - out_edges: HashMap>, - in_edges: HashMap>, -} - -impl IntermediateNetwork { - pub fn nodes(&self) -> Vec { - self.out_edges.keys().cloned().collect::>() - } - pub fn out_edges(&self, node: NodeId) -> Option<&HashMap> { - self.out_edges.get(&node) - } - - pub fn in_edges(&self, node: NodeId) -> Option<&HashMap> { - self.in_edges.get(&node) - } -} -impl IntermediateNetwork { - pub fn add_edge(&mut self, edge: IntermediateEdge) { - let source = edge.source; - let target = edge.target; - self.out_edges - .entry(source) - .or_default() - .insert(target, edge.clone()); - - self.in_edges - .entry(target) - .or_default() - .insert(source, edge.clone()); - } - - pub fn remove_node(&mut self, node: NodeId) { - if let Some(outs) = self.out_edges.get(&node) { - for edge in outs.values() { - self.in_edges.entry(edge.target).and_modify(|x| { - x.remove(&node); - }); - } - } - - if let Some(ins) = self.in_edges.get(&node) { - for edge in ins.values() { - self.out_edges.entry(edge.source).and_modify(|x| { - x.remove(&node); - }); - } - } - - self.out_edges.remove(&node); - self.in_edges.remove(&node); - } - - pub fn bypass(&mut self, node: NodeId) -> Vec { - let parents = if let Some(parents) = self.in_edges(node) { - parents - } else { - self.remove_node(node); - return vec![]; - }; - let children = if let Some(children) = self.out_edges(node) { - children - } else { - self.remove_node(node); - return vec![]; - }; - - let mut collects = Vec::new(); - - for (parent, parent_edge) in parents { - debug_assert_eq!(parent, &parent_edge.source); - for (child, child_edge) in children { - debug_assert_eq!(child, &child_edge.target); - if parent.0 != child.0 { - let distance = parent_edge.weight + child_edge.weight; - let (state, road_ids) = collect_shortcut_data_edges(parent_edge, child_edge); - let shortcut = IntermediateEdge::new( - *parent, - *child, - distance, - ShortcutState::Shortcut(state), - ShortcutState::Shortcut(road_ids), - EdgeDirection::Forward, - ); - - collects.push(shortcut); - } - } - } - - let touched = parents.keys().chain(children.keys()).cloned().collect(); - - self.remove_node(node); - - for shortcut in collects { - self.add_edge(shortcut) - } - - touched - } -} - -fn collect_shortcut_data_edges( - parent_edge: &IntermediateEdge, - child_edge: &IntermediateEdge, -) -> (Vec, Vec) { - let mut edge_id_a = Vec::from(parent_edge.data.clone()); - let mut road_id_a = Vec::from(parent_edge.road_id.clone()); - - edge_id_a.extend(Vec::from(child_edge.data.clone())); - road_id_a.extend(Vec::from(child_edge.road_id.clone())); - - (edge_id_a, road_id_a) -} - -impl FromIterator for IntermediateNetwork { - fn from_iter>(iter: T) -> Self { - let mut intermediate = IntermediateNetwork::default(); - for edge in iter.into_iter() { - intermediate.add_edge(edge); - } - - intermediate - } -} - -impl FromParallelIterator for IntermediateNetwork { - fn from_par_iter(par_iter: I) -> Self - where - I: rayon::iter::IntoParallelIterator, - { - let mut intermediate = IntermediateNetwork::default(); - let edges = par_iter.into_par_iter().collect::>(); - println!("Collected"); - for edge in edges { - intermediate.add_edge(edge); - } - - intermediate - } -} - -#[derive(Debug, Default, Clone, Serialize, Deserialize)] -pub struct IntermediateData { - references: HashMap, - shortcuts: HashMap>, - road_ids: HashMap>, -} - -impl NetworkData for IntermediateData { - type NodeData = NodeId; - type EdgeData = ShortcutState; +impl EdgeBuilder for IntermediateEdge { + type GraphData = IntermediateData; - fn node_data(&self, node: NodeId) -> &Self::NodeData { - &self.references[&node] + fn source(&self) -> NodeId { + self.source } - fn edge_data(&self, edge: EdgeId) -> &Self::EdgeData { - &self.shortcuts[&edge] + fn target(&self) -> NodeId { + self.target } - fn with_size(node_size: usize, edge_size: usize) -> Self { - Self { - references: HashMap::with_capacity(node_size), - shortcuts: HashMap::with_capacity(edge_size), - road_ids: HashMap::with_capacity(edge_size), - } + fn weight(&self) -> f32 { + self.weight } - fn add_node(&mut self, _: NodeId, _: Self::NodeData) {} - - fn add_edge(&mut self, edge: EdgeId, data: Self::EdgeData, road_id: ShortcutState) { - self.shortcuts.insert(edge, data); - self.road_ids.insert(edge, road_id); + fn road_id(&self) -> ShortcutState { + self.road_id.clone() } - fn edge_road_id(&self, edge: EdgeId) -> ShortcutState { - self.road_ids[&edge].clone() + fn edge_data(&self) -> ::EdgeData { + self.data.clone() } } -impl From for DirectedNetworkGraph { - fn from(val: IntermediateNetwork) -> Self { - let mut builder = DirectedNetworkBuilder::::new(); - - for node in val.nodes() { - for (_, edge) in val.out_edges(node).unwrap() { - let n1 = builder.add_node(IntermediateNode(edge.source)); - let n2 = builder.add_node(IntermediateNode(edge.target)); - - builder.add_edge(IntermediateEdge { - source: n1, - target: n2, - ..edge.clone() - }); - } - } - - builder.build() - } -} +// impl NodeBuilder for IntermediateNode { +// type Data = NodeId; + +// fn id(&self) -> u32 { +// self.0 .0 +// } + +// fn data(&self) -> Self::Data { +// self.0 +// } +// } + +// impl EdgeBuilder for IntermediateEdge { +// type Data = ShortcutState; // Points to road_id + +// fn data(&self) -> Self::Data { +// self.data.clone() +// } + +// fn source(&self) -> NodeId { +// self.source +// } + +// fn target(&self) -> NodeId { +// self.target +// } + +// fn weight(&self) -> f32 { +// self.weight +// } + +// fn direction(&self) -> EdgeDirection { +// self.direction +// } + +// fn road_id(&self) -> ShortcutState { +// self.road_id.clone() +// } +// } + +// // #[derive(Debug, Default)] +// // pub(crate) struct IntermediateNetwork { +// // out_edges: HashMap>, +// // in_edges: HashMap>, +// // } + +// impl IntermediateNetwork { +// pub fn nodes(&self) -> Vec { +// self.out_edges.keys().cloned().collect::>() +// } +// pub fn out_edges(&self, node: NodeId) -> Option<&HashMap> { +// self.out_edges.get(&node) +// } + +// pub fn in_edges(&self, node: NodeId) -> Option<&HashMap> { +// self.in_edges.get(&node) +// } +// } +// impl IntermediateNetwork { +// pub fn add_edge(&mut self, edge: IntermediateEdge) { +// let source = edge.source; +// let target = edge.target; +// self.out_edges +// .entry(source) +// .or_default() +// .insert(target, edge.clone()); + +// self.in_edges +// .entry(target) +// .or_default() +// .insert(source, edge.clone()); +// } + +// pub fn remove_node(&mut self, node: NodeId) { +// if let Some(outs) = self.out_edges.get(&node) { +// for edge in outs.values() { +// self.in_edges.entry(edge.target).and_modify(|x| { +// x.remove(&node); +// }); +// } +// } + +// if let Some(ins) = self.in_edges.get(&node) { +// for edge in ins.values() { +// self.out_edges.entry(edge.source).and_modify(|x| { +// x.remove(&node); +// }); +// } +// } + +// self.out_edges.remove(&node); +// self.in_edges.remove(&node); +// } + +// pub fn bypass(&mut self, node: NodeId) -> Vec { +// let parents = if let Some(parents) = self.in_edges(node) { +// parents +// } else { +// self.remove_node(node); +// return vec![]; +// }; +// let children = if let Some(children) = self.out_edges(node) { +// children +// } else { +// self.remove_node(node); +// return vec![]; +// }; + +// let mut collects = Vec::new(); + +// for (parent, parent_edge) in parents { +// debug_assert_eq!(parent, &parent_edge.source); +// for (child, child_edge) in children { +// debug_assert_eq!(child, &child_edge.target); +// if parent.0 != child.0 { +// let distance = parent_edge.weight + child_edge.weight; +// let (state, road_ids) = collect_shortcut_data_edges(parent_edge, child_edge); +// let shortcut = IntermediateEdge::new( +// *parent, +// *child, +// distance, +// ShortcutState::Shortcut(state), +// ShortcutState::Shortcut(road_ids), +// EdgeDirection::Forward, +// ); + +// collects.push(shortcut); +// } +// } +// } + +// let touched = parents.keys().chain(children.keys()).cloned().collect(); + +// self.remove_node(node); + +// for shortcut in collects { +// self.add_edge(shortcut) +// } + +// touched +// } +// } + +// fn collect_shortcut_data_edges( +// parent_edge: &IntermediateEdge, +// child_edge: &IntermediateEdge, +// ) -> (Vec, Vec) { +// let mut edge_id_a = Vec::from(parent_edge.data.clone()); +// let mut road_id_a = Vec::from(parent_edge.road_id.clone()); + +// edge_id_a.extend(Vec::from(child_edge.data.clone())); +// road_id_a.extend(Vec::from(child_edge.road_id.clone())); + +// (edge_id_a, road_id_a) +// } + +// impl FromIterator for IntermediateNetwork { +// fn from_iter>(iter: T) -> Self { +// let mut intermediate = IntermediateNetwork::default(); +// for edge in iter.into_iter() { +// intermediate.add_edge(edge); +// } + +// intermediate +// } +// } + +// impl FromParallelIterator for IntermediateNetwork { +// fn from_par_iter(par_iter: I) -> Self +// where +// I: rayon::iter::IntoParallelIterator, +// { +// let mut intermediate = IntermediateNetwork::default(); +// let edges = par_iter.into_par_iter().collect::>(); +// println!("Collected"); +// for edge in edges { +// intermediate.add_edge(edge); +// } + +// intermediate +// } +// } + +// #[derive(Debug, Default, Clone, Serialize, Deserialize)] +// pub struct IntermediateData { +// references: HashMap, +// shortcuts: HashMap>, +// road_ids: HashMap>, +// } + +// impl NetworkData for IntermediateData { +// type NodeData = NodeId; +// type EdgeData = ShortcutState; + +// fn node_data(&self, node: NodeId) -> &Self::NodeData { +// &self.references[&node] +// } + +// fn edge_data(&self, edge: EdgeId) -> &Self::EdgeData { +// &self.shortcuts[&edge] +// } + +// fn with_size(node_size: usize, edge_size: usize) -> Self { +// Self { +// references: HashMap::with_capacity(node_size), +// shortcuts: HashMap::with_capacity(edge_size), +// road_ids: HashMap::with_capacity(edge_size), +// } +// } + +// fn add_node(&mut self, _: NodeId, _: Self::NodeData) {} + +// fn add_edge(&mut self, edge: EdgeId, data: Self::EdgeData, road_id: ShortcutState) { +// self.shortcuts.insert(edge, data); +// self.road_ids.insert(edge, road_id); +// } + +// fn edge_road_id(&self, edge: EdgeId) -> ShortcutState { +// self.road_ids[&edge].clone() +// } +// } + +// impl From for DirectedNetworkGraph { +// fn from(val: IntermediateNetwork) -> Self { +// let mut builder = DirectedNetworkBuilder::::new(); + +// for node in val.nodes() { +// for (_, edge) in val.out_edges(node).unwrap() { +// let n1 = builder.add_node(IntermediateNode(edge.source)); +// let n2 = builder.add_node(IntermediateNode(edge.target)); + +// builder.add_edge(IntermediateEdge { +// source: n1, +// target: n2, +// ..edge.clone() +// }); +// } +// } + +// builder.build() +// } +// } diff --git a/components/highway/src/generation/mod.rs b/components/highway/src/generation/mod.rs index 913554d..7c2c9cf 100644 --- a/components/highway/src/generation/mod.rs +++ b/components/highway/src/generation/mod.rs @@ -1,8 +1,9 @@ -use self::intermediate_network::{IntermediateData, IntermediateNetwork}; use crate::generation::intermediate_network::IntermediateEdge; use graph::{ - BackwardNeighbourhood, DirectedNetworkGraph, ForwardNeighbourhood, NetworkData, ShortcutState, + directed_map_graph::DirectedMapGraph, BackwardNeighbourhood, DirectedNetworkGraph, + ForwardNeighbourhood, NetworkData, ShortcutState, }; +use intermediate_network::{IntermediateData, IntermediateNetwork}; use rayon::prelude::*; use std::collections::HashSet; @@ -61,7 +62,7 @@ pub fn calculate_layer( pub(crate) fn phase_1( size: usize, network: &DirectedNetworkGraph, -) -> IntermediateNetwork { +) -> DirectedMapGraph { println!("Start computing (forward backward)"); let (duration, computed) = stopwatch!(ComputedState::new(size, network)); @@ -88,23 +89,23 @@ pub(crate) fn phase_1( duration.as_millis() ); - let edges = edges + let graph = edges .into_iter() .map(|(source, edge_id)| { let edge = network.edge(edge_id); IntermediateEdge::new( source, edge.target(), - edge.distance(), + edge.weight(), ShortcutState::Single(edge.edge_id), network.data.edge_road_id(edge_id), - graph::builder::EdgeDirection::Forward, + graph::EdgeDirection::Forward, ) }) .collect(); println!("Finished computing (edges collections)"); - edges + graph } /** diff --git a/components/highway/src/query/mod.rs b/components/highway/src/query/mod.rs index e0524b1..eb47c80 100644 --- a/components/highway/src/query/mod.rs +++ b/components/highway/src/query/mod.rs @@ -1,7 +1,6 @@ +use graph::{highway_network::HighwayNetwork, EdgeDirection, NodeId}; use std::collections::BinaryHeap; -use graph::{builder::EdgeDirection, highway_network::HighwayNetwork, NodeId}; - pub fn shortest_path(source: NodeId, target: NodeId, network: &HighwayNetwork) { let mut forward = HighwayDijkstraIterator::default(); let mut backward = HighwayDijkstraIterator::default(); diff --git a/src/ui/route.rs b/src/ui/route.rs index 6528406..c8fd8f5 100644 --- a/src/ui/route.rs +++ b/src/ui/route.rs @@ -173,7 +173,7 @@ fn explore_node( ) { for (id, edge) in network.out_edges(source) { let target = edge.target(); - let distance = old_distance + edge.distance(); + let distance = old_distance + edge.weight(); heap.push((Reverse(F32(distance)), F32(distance), target, (source, id))); }