|
|
@ -1,6 +1,6 @@
|
|
|
|
use std::{
|
|
|
|
use std::{
|
|
|
|
cell::RefCell,
|
|
|
|
cell::RefCell,
|
|
|
|
collections::{BTreeMap, HashMap, HashSet, VecDeque},
|
|
|
|
collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque},
|
|
|
|
fmt::Debug,
|
|
|
|
fmt::Debug,
|
|
|
|
hash::Hash,
|
|
|
|
hash::Hash,
|
|
|
|
rc::Rc,
|
|
|
|
rc::Rc,
|
|
|
@ -13,41 +13,48 @@ use super::{AdjacencyGraph, UndirectedGraph};
|
|
|
|
#[allow(dead_code)]
|
|
|
|
#[allow(dead_code)]
|
|
|
|
impl<V> AdjacencyGraph<V>
|
|
|
|
impl<V> AdjacencyGraph<V>
|
|
|
|
where
|
|
|
|
where
|
|
|
|
V: Hash + Eq + Clone + Debug,
|
|
|
|
V: Ord + Clone + Debug,
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pub fn new() -> Self {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
AdjacencyGraph {
|
|
|
|
AdjacencyGraph {
|
|
|
|
nodes: HashSet::new(),
|
|
|
|
nodes: BTreeSet::new(),
|
|
|
|
adjacencies: HashMap::new(),
|
|
|
|
adjacencies: BTreeMap::new(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub fn from_edges(edges: &[(V, V)]) -> Self {
|
|
|
|
|
|
|
|
let mut graph = AdjacencyGraph::new();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (from, to) in edges {
|
|
|
|
|
|
|
|
graph.add_edge(from.clone(), to.clone());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
graph
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn add_node(&mut self, node: V) {
|
|
|
|
pub fn add_node(&mut self, node: V) {
|
|
|
|
// O(1)
|
|
|
|
|
|
|
|
self.nodes.insert(node);
|
|
|
|
self.nodes.insert(node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn add_edge(&mut self, from: V, to: V) {
|
|
|
|
pub fn add_edge(&mut self, from: V, to: V) {
|
|
|
|
// O(1)
|
|
|
|
|
|
|
|
self.add_node(from.clone());
|
|
|
|
self.add_node(from.clone());
|
|
|
|
self.add_node(to.clone());
|
|
|
|
self.add_node(to.clone());
|
|
|
|
|
|
|
|
|
|
|
|
// O(1)
|
|
|
|
|
|
|
|
self.adjacencies
|
|
|
|
self.adjacencies
|
|
|
|
.entry(from)
|
|
|
|
.entry(from)
|
|
|
|
.or_insert_with(HashSet::new)
|
|
|
|
.or_insert_with(BTreeSet::new)
|
|
|
|
.insert(to);
|
|
|
|
.insert(to);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn get_adjacencies(&self, node: &V) -> Option<&HashSet<V>> {
|
|
|
|
pub fn get_adjacencies(&self, node: &V) -> Option<&BTreeSet<V>> {
|
|
|
|
self.adjacencies.get(node)
|
|
|
|
self.adjacencies.get(node)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn adjacencies(&self) -> &HashMap<V, HashSet<V>> {
|
|
|
|
pub fn adjacencies(&self) -> &BTreeMap<V, BTreeSet<V>> {
|
|
|
|
&self.adjacencies
|
|
|
|
&self.adjacencies
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn nodes(&self) -> &HashSet<V> {
|
|
|
|
pub fn nodes(&self) -> &BTreeSet<V> {
|
|
|
|
&self.nodes
|
|
|
|
&self.nodes
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -91,7 +98,7 @@ where
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn dfs<'a>(&'a self, node: &'a V) -> impl Iterator<Item = V> + 'a {
|
|
|
|
pub fn dfs<'a>(&'a self, node: &'a V) -> impl Iterator<Item = V> + 'a {
|
|
|
|
let mut visited = HashSet::new();
|
|
|
|
let mut visited = BTreeSet::new();
|
|
|
|
let mut stack = VecDeque::from([node]);
|
|
|
|
let mut stack = VecDeque::from([node]);
|
|
|
|
|
|
|
|
|
|
|
|
std::iter::from_fn(move || {
|
|
|
|
std::iter::from_fn(move || {
|
|
|
@ -113,7 +120,7 @@ where
|
|
|
|
|
|
|
|
|
|
|
|
/// This computes if this undirected graph is cyclic or not by searching for an oriented cycle in the graph
|
|
|
|
/// This computes if this undirected graph is cyclic or not by searching for an oriented cycle in the graph
|
|
|
|
pub fn is_cyclic(&self) -> bool {
|
|
|
|
pub fn is_cyclic(&self) -> bool {
|
|
|
|
let mut remaining_nodes = self.nodes.iter().collect::<HashSet<_>>();
|
|
|
|
let mut remaining_nodes = self.nodes.iter().collect::<BTreeSet<_>>();
|
|
|
|
|
|
|
|
|
|
|
|
// let progress_bar = ProgressBar::new(self.nodes.len() as u64);
|
|
|
|
// let progress_bar = ProgressBar::new(self.nodes.len() as u64);
|
|
|
|
// let mut visited_count = 0;
|
|
|
|
// let mut visited_count = 0;
|
|
|
@ -125,7 +132,7 @@ where
|
|
|
|
remaining_nodes.remove(start);
|
|
|
|
remaining_nodes.remove(start);
|
|
|
|
// progress_bar.inc(1);
|
|
|
|
// progress_bar.inc(1);
|
|
|
|
|
|
|
|
|
|
|
|
let mut dfs_visited = HashSet::new();
|
|
|
|
let mut dfs_visited = BTreeSet::new();
|
|
|
|
let mut stack = VecDeque::new();
|
|
|
|
let mut stack = VecDeque::new();
|
|
|
|
stack.push_back(start);
|
|
|
|
stack.push_back(start);
|
|
|
|
|
|
|
|
|
|
|
@ -154,12 +161,12 @@ where
|
|
|
|
false
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn shortest_path_matrix(&self) -> HashMap<&V, HashMap<&V, usize>> {
|
|
|
|
pub fn shortest_path_matrix(&self) -> BTreeMap<&V, BTreeMap<&V, usize>> {
|
|
|
|
let mut result = HashMap::new();
|
|
|
|
let mut result = BTreeMap::new();
|
|
|
|
|
|
|
|
|
|
|
|
for node in self.nodes.iter() {
|
|
|
|
for node in self.nodes.iter() {
|
|
|
|
let mut distances = HashMap::new();
|
|
|
|
let mut distances = BTreeMap::new();
|
|
|
|
let mut visited = HashSet::new();
|
|
|
|
let mut visited = BTreeSet::new();
|
|
|
|
let mut queue = VecDeque::from([node]);
|
|
|
|
let mut queue = VecDeque::from([node]);
|
|
|
|
|
|
|
|
|
|
|
|
distances.insert(node, 0);
|
|
|
|
distances.insert(node, 0);
|
|
|
@ -190,7 +197,7 @@ where
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn compute_ccs(&self) -> Vec<Vec<V>> {
|
|
|
|
pub fn compute_ccs(&self) -> Vec<Vec<V>> {
|
|
|
|
let mut visited = HashSet::new();
|
|
|
|
let mut visited = BTreeSet::new();
|
|
|
|
let mut result = Vec::new();
|
|
|
|
let mut result = Vec::new();
|
|
|
|
|
|
|
|
|
|
|
|
let op = self.opposite();
|
|
|
|
let op = self.opposite();
|
|
|
@ -210,7 +217,7 @@ where
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let mut cc: HashSet<V> = HashSet::new();
|
|
|
|
let mut cc: BTreeSet<V> = BTreeSet::new();
|
|
|
|
let mut stack: Vec<&V> = vec![node];
|
|
|
|
let mut stack: Vec<&V> = vec![node];
|
|
|
|
|
|
|
|
|
|
|
|
while let Some(node) = stack.pop() {
|
|
|
|
while let Some(node) = stack.pop() {
|
|
|
@ -240,82 +247,82 @@ where
|
|
|
|
result
|
|
|
|
result
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn compute_ccs_2(&self) -> Vec<Vec<V>> {
|
|
|
|
// pub fn compute_ccs_2(&self) -> Vec<Vec<V>> {
|
|
|
|
let mut cc: HashMap<V, Rc<RefCell<HashSet<V>>>> = HashMap::new();
|
|
|
|
// let mut cc: BTreeMap<V, Rc<RefCell<BTreeSet<V>>>> = BTreeMap::new();
|
|
|
|
|
|
|
|
|
|
|
|
for node in self.nodes.iter() {
|
|
|
|
// for node in self.nodes.iter() {
|
|
|
|
if cc.contains_key(&node) {
|
|
|
|
// if cc.contains_key(&node) {
|
|
|
|
continue;
|
|
|
|
// continue;
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// println!("All CC: {:?}", cc);
|
|
|
|
// // println!("All CC: {:?}", cc);
|
|
|
|
|
|
|
|
|
|
|
|
let new_cc = Rc::new(RefCell::new(HashSet::new()));
|
|
|
|
// let new_cc = Rc::new(RefCell::new(HashSet::new()));
|
|
|
|
|
|
|
|
|
|
|
|
let mut stack: Vec<&V> = vec![node];
|
|
|
|
// let mut stack: Vec<&V> = vec![node];
|
|
|
|
|
|
|
|
|
|
|
|
while let Some(node) = stack.pop() {
|
|
|
|
// while let Some(node) = stack.pop() {
|
|
|
|
// println!("New CC: {:?}", new_cc.borrow());
|
|
|
|
// // println!("New CC: {:?}", new_cc.borrow());
|
|
|
|
|
|
|
|
|
|
|
|
if cc.contains_key(&node) {
|
|
|
|
// if cc.contains_key(&node) {
|
|
|
|
// merge the two connected components and go to the next node
|
|
|
|
// // merge the two connected components and go to the next node
|
|
|
|
|
|
|
|
|
|
|
|
let old_cc: &Rc<RefCell<HashSet<V>>> = cc.get(&node).unwrap();
|
|
|
|
// let old_cc: &Rc<RefCell<HashSet<V>>> = cc.get(&node).unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
// println!(
|
|
|
|
// // println!(
|
|
|
|
// "Merging {:?} with {:?} due to link to {:?}",
|
|
|
|
// // "Merging {:?} with {:?} due to link to {:?}",
|
|
|
|
// new_cc.borrow(),
|
|
|
|
// // new_cc.borrow(),
|
|
|
|
// old_cc.borrow(),
|
|
|
|
// // old_cc.borrow(),
|
|
|
|
// node
|
|
|
|
// // node
|
|
|
|
// );
|
|
|
|
// // );
|
|
|
|
|
|
|
|
|
|
|
|
new_cc
|
|
|
|
// new_cc
|
|
|
|
.borrow_mut()
|
|
|
|
// .borrow_mut()
|
|
|
|
.extend(old_cc.borrow().iter().map(|x| x.to_owned()));
|
|
|
|
// .extend(old_cc.borrow().iter().map(|x| x.to_owned()));
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
// break;
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
if new_cc.borrow().contains(&node) {
|
|
|
|
// if new_cc.borrow().contains(&node) {
|
|
|
|
continue;
|
|
|
|
// continue;
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
new_cc.borrow_mut().insert(node.clone());
|
|
|
|
// new_cc.borrow_mut().insert(node.clone());
|
|
|
|
|
|
|
|
|
|
|
|
if let Some(adjacencies) = self.get_adjacencies(&node) {
|
|
|
|
// if let Some(adjacencies) = self.get_adjacencies(&node) {
|
|
|
|
for adj in adjacencies {
|
|
|
|
// for adj in adjacencies {
|
|
|
|
stack.push(adj);
|
|
|
|
// stack.push(adj);
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
for n in new_cc.borrow().iter() {
|
|
|
|
// for n in new_cc.borrow().iter() {
|
|
|
|
cc.insert(n.to_owned(), new_cc.clone());
|
|
|
|
// cc.insert(n.to_owned(), new_cc.clone());
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// extract the unique connected components by pointers
|
|
|
|
// // extract the unique connected components by pointers
|
|
|
|
let mut result = Vec::new();
|
|
|
|
// let mut result = Vec::new();
|
|
|
|
let mut seen = HashSet::new();
|
|
|
|
// let mut seen = HashSet::new();
|
|
|
|
|
|
|
|
|
|
|
|
for node in self.nodes.iter() {
|
|
|
|
// for node in self.nodes.iter() {
|
|
|
|
if seen.contains(node) {
|
|
|
|
// if seen.contains(node) {
|
|
|
|
continue;
|
|
|
|
// continue;
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
let cc = cc.get(node).unwrap();
|
|
|
|
// let cc = cc.get(node).unwrap();
|
|
|
|
seen.extend(cc.borrow().iter().map(|x| x.to_owned()));
|
|
|
|
// seen.extend(cc.borrow().iter().map(|x| x.to_owned()));
|
|
|
|
|
|
|
|
|
|
|
|
result.push(cc.borrow().iter().map(|x| x.to_owned()).collect());
|
|
|
|
// result.push(cc.borrow().iter().map(|x| x.to_owned()).collect());
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
result
|
|
|
|
// result
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
/// This function prints the number of nodes, edges and a histogram of the degrees of the nodes
|
|
|
|
/// This function prints the number of nodes, edges and a histogram of the degrees of the nodes
|
|
|
|
/// in the graph (computing the degrees might take a long time)
|
|
|
|
/// in the graph (computing the degrees might take a long time)
|
|
|
|
pub fn print_stats(&self) {
|
|
|
|
pub fn print_stats(&self) {
|
|
|
|
let mut vertices_degrees = HashMap::new();
|
|
|
|
let mut vertices_degrees = BTreeMap::new();
|
|
|
|
|
|
|
|
|
|
|
|
for (from, tos) in self
|
|
|
|
for (from, tos) in self
|
|
|
|
.adjacencies
|
|
|
|
.adjacencies
|
|
|
@ -356,10 +363,10 @@ where
|
|
|
|
|
|
|
|
|
|
|
|
impl<V> UndirectedGraph<V>
|
|
|
|
impl<V> UndirectedGraph<V>
|
|
|
|
where
|
|
|
|
where
|
|
|
|
V: Hash + Eq + Clone + Debug,
|
|
|
|
V: Ord + Eq + Clone + Debug,
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pub fn connected_components(&self) -> Vec<Vec<V>> {
|
|
|
|
pub fn connected_components(&self) -> Vec<Vec<V>> {
|
|
|
|
let mut visited = HashSet::new();
|
|
|
|
let mut visited = BTreeSet::new();
|
|
|
|
let mut result = Vec::new();
|
|
|
|
let mut result = Vec::new();
|
|
|
|
|
|
|
|
|
|
|
|
for node in self.graph.nodes.iter() {
|
|
|
|
for node in self.graph.nodes.iter() {
|
|
|
@ -367,7 +374,7 @@ where
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let mut cc: HashSet<V> = HashSet::new();
|
|
|
|
let mut cc: BTreeSet<V> = BTreeSet::new();
|
|
|
|
let mut stack: Vec<&V> = vec![node];
|
|
|
|
let mut stack: Vec<&V> = vec![node];
|
|
|
|
|
|
|
|
|
|
|
|
while let Some(node) = stack.pop() {
|
|
|
|
while let Some(node) = stack.pop() {
|
|
|
|