From ad2dd339ff0b6a49c6735f9e69eba228bbca1006 Mon Sep 17 00:00:00 2001 From: Antonio De Lucreziis Date: Wed, 30 Oct 2024 00:46:28 +0100 Subject: [PATCH] chore: more cleaned up in directed graphs --- src/graph/algorithms.rs | 147 ---------------------------------------- src/graph/directed.rs | 131 ++++++++++++++++++++++++++++++++++- src/graph/mod.rs | 1 - 3 files changed, 129 insertions(+), 150 deletions(-) delete mode 100644 src/graph/algorithms.rs diff --git a/src/graph/algorithms.rs b/src/graph/algorithms.rs deleted file mode 100644 index 1df0187..0000000 --- a/src/graph/algorithms.rs +++ /dev/null @@ -1,147 +0,0 @@ -#![allow(dead_code)] - -use std::{ - collections::{BTreeMap, BTreeSet, VecDeque}, - fmt::Debug, -}; - -use indicatif::ProgressIterator; - -use super::{AdjacencyGraph, Graph, UndirectedGraph}; - -#[allow(dead_code)] -impl AdjacencyGraph -where - V: Ord + Eq + Clone + Debug, -{ - pub fn opposite(&self) -> AdjacencyGraph { - let mut opposite = AdjacencyGraph::new(); - - // O(|E|) - for (from, to) in self.edges() { - opposite.add_edge(to, from); - } - - opposite - } - - pub fn undirected(&self) -> UndirectedGraph { - let mut undirected = AdjacencyGraph::new(); - - // O(|E|) - for (from, to) in self.edges() { - undirected.add_edge(from.clone(), to.clone()); - undirected.add_edge(to.clone(), from.clone()); - } - - UndirectedGraph { - directed: undirected, - } - } - - pub fn restricted(&self, nodes: &Vec) -> AdjacencyGraph { - let nodes_index = nodes.iter().collect::>(); - let mut restricted = AdjacencyGraph::new(); - - for node in nodes { - for adj in self.neighbors(&node) { - if nodes_index.contains(&adj) { - restricted.add_edge(node.clone(), adj.clone()); - } - } - } - - restricted - } - - pub fn has_edge(&self, from: &V, to: &V) -> bool { - self.neighbors(from).contains(to) - } - - pub fn shortest_path_matrix(&self) -> BTreeMap> { - let mut result = BTreeMap::new(); - - for node in self.nodes.iter() { - let mut distances = BTreeMap::new(); - let mut visited = BTreeSet::new(); - let mut queue = VecDeque::from([node.clone()]); - - distances.insert(node.clone(), 0); - - while let Some(node) = queue.pop_front() { - if visited.contains(&node) { - continue; - } - - visited.insert(node.clone()); - - let distance = *distances.get(&node).unwrap(); - - for adj in self.neighbors(&node) { - if !distances.contains_key(&adj) { - distances.insert(adj.clone(), distance + 1); - queue.push_back(adj.clone()); - } - } - } - - result.insert(node.clone(), distances); - } - - result - } - - pub fn compute_ccs(&self) -> Vec> { - let mut visited = BTreeSet::new(); - let mut result = Vec::new(); - - let op = self.opposite(); - - println!("Computing connected components..."); - - for node in self.nodes.iter().progress() { - if visited.contains(node) { - continue; - } - - let mut cc: BTreeSet = BTreeSet::new(); - let mut stack: Vec = vec![node.clone()]; - - while let Some(node) = stack.pop() { - if cc.contains(&node) { - continue; - } - - cc.insert(node.clone()); - - for adj in self.neighbors(&node) { - stack.push(adj); - } - - for adj in op.neighbors(&node) { - stack.push(adj); - } - } - - visited.extend(cc.iter().map(|x| x.to_owned())); - result.push(cc.iter().map(|x| x.to_owned()).collect()); - } - - result - } - - pub fn gc(&mut self) { - let mut to_remove = Vec::new(); - - for node in self.nodes.iter() { - if self.neighbors(node).is_empty() { - to_remove.push(node.clone()); - } - } - - for node in to_remove { - self.nodes.remove(&node); - self.adjacencies.remove(&node); - } - } -} diff --git a/src/graph/directed.rs b/src/graph/directed.rs index 332f183..93bb4e8 100644 --- a/src/graph/directed.rs +++ b/src/graph/directed.rs @@ -1,6 +1,11 @@ -use std::collections::{BTreeMap, BTreeSet}; +use std::{ + collections::{BTreeMap, BTreeSet, VecDeque}, + fmt::Debug, +}; -use super::{AdjacencyGraph, Graph}; +use indicatif::ProgressIterator; + +use super::{AdjacencyGraph, Graph, UndirectedGraph}; impl Graph for AdjacencyGraph where @@ -72,3 +77,125 @@ where } } } + +#[allow(dead_code)] +impl AdjacencyGraph +where + V: Ord + Eq + Clone + Debug, +{ + pub fn opposite(&self) -> AdjacencyGraph { + let mut opposite = AdjacencyGraph::new(); + + // O(|E|) + for (from, to) in self.edges() { + opposite.add_edge(to, from); + } + + opposite + } + + pub fn undirected(&self) -> UndirectedGraph { + let mut undirected = AdjacencyGraph::new(); + + // O(|E|) + for (from, to) in self.edges() { + undirected.add_edge(from.clone(), to.clone()); + undirected.add_edge(to.clone(), from.clone()); + } + + UndirectedGraph { + directed: undirected, + } + } + + pub fn has_edge(&self, from: &V, to: &V) -> bool { + self.neighbors(from).contains(to) + } + + pub fn shortest_path_matrix(&self) -> BTreeMap> { + let mut result = BTreeMap::new(); + + for node in self.nodes.iter() { + let mut distances = BTreeMap::new(); + let mut visited = BTreeSet::new(); + let mut queue = VecDeque::from([node.clone()]); + + distances.insert(node.clone(), 0); + + while let Some(node) = queue.pop_front() { + if visited.contains(&node) { + continue; + } + + visited.insert(node.clone()); + + let distance = *distances.get(&node).unwrap(); + + for adj in self.neighbors(&node) { + if !distances.contains_key(&adj) { + distances.insert(adj.clone(), distance + 1); + queue.push_back(adj.clone()); + } + } + } + + result.insert(node.clone(), distances); + } + + result + } + + pub fn compute_ccs(&self) -> Vec> { + let mut visited = BTreeSet::new(); + let mut result = Vec::new(); + + let op = self.opposite(); + + println!("Computing connected components..."); + + for node in self.nodes.iter().progress() { + if visited.contains(node) { + continue; + } + + let mut cc: BTreeSet = BTreeSet::new(); + let mut stack: Vec = vec![node.clone()]; + + while let Some(node) = stack.pop() { + if cc.contains(&node) { + continue; + } + + cc.insert(node.clone()); + + for adj in self.neighbors(&node) { + stack.push(adj); + } + + for adj in op.neighbors(&node) { + stack.push(adj); + } + } + + visited.extend(cc.iter().map(|x| x.to_owned())); + result.push(cc.iter().map(|x| x.to_owned()).collect()); + } + + result + } + + pub fn gc(&mut self) { + let mut to_remove = Vec::new(); + + for node in self.nodes.iter() { + if self.neighbors(node).is_empty() { + to_remove.push(node.clone()); + } + } + + for node in to_remove { + self.nodes.remove(&node); + self.adjacencies.remove(&node); + } + } +} diff --git a/src/graph/mod.rs b/src/graph/mod.rs index 0f741ec..15821a8 100644 --- a/src/graph/mod.rs +++ b/src/graph/mod.rs @@ -78,7 +78,6 @@ pub struct DirectedAcyclicGraph(pub AdjacencyGraph) where V: Clone; -pub mod algorithms; pub mod dag; pub mod directed; pub mod edge_types;