use std::iter::Sum;
use itertools::max;
use fxhash::{FxHashMap, FxHashSet};
use crate::iterators::*;
use crate::graph::*;
#[derive(Debug)]
pub struct EditGraph {
adj: FxHashMap<Vertex, VertexSet>,
degs: FxHashMap<Vertex, u32>,
m: usize
}
impl PartialEq for EditGraph {
fn eq(&self, other: &Self) -> bool {
if self.num_vertices() != other.num_vertices() {
return false
}
if self.num_edges() != other.num_edges() {
return false
}
if self.degs != other.degs {
return false
}
self.adj == other.adj
}
}
impl Eq for EditGraph {}
impl Clone for EditGraph {
fn clone(&self) -> EditGraph {
let mut G = EditGraph::new();
for v in self.vertices() {
G.add_vertex(v);
for u in self.neighbours(v) {
G.add_edge(u, v);
}
}
G
}
}
impl Graph for EditGraph {
fn num_vertices(&self) -> usize {
self.adj.len()
}
fn num_edges(&self) -> usize {
self.m
}
fn adjacent(&self, u:&Vertex, v:&Vertex) -> bool {
match self.adj.get(u) {
Some(N) => N.contains(v),
_ => false
}
}
fn degree(&self, u:&Vertex) -> u32 {
*self.degs.get(u).unwrap_or(&0)
}
fn contains(&self, u:&Vertex) -> bool {
self.adj.contains_key(u)
}
fn vertices<'a>(&'a self) -> Box<dyn Iterator<Item=&Vertex> + 'a> {
Box::new(self.adj.keys())
}
fn neighbours<'a>(&'a self, u:&Vertex) -> Box<dyn Iterator<Item=&Vertex> + 'a> {
match self.adj.get(u) {
Some(N) => Box::new(N.iter()),
None => panic!("Vertex not contained in EditGraph")
}
}
}
impl FromIterator<Edge> for EditGraph {
fn from_iter<T: IntoIterator<Item = Edge>>(iter: T) -> Self {
let mut res = EditGraph::new();
for (u,v) in iter {
res.add_edge(&u, &v);
}
res
}
}
impl MutableGraph for EditGraph {
fn new() -> EditGraph {
EditGraph{adj: FxHashMap::default(),
degs: FxHashMap::default(),
m: 0}
}
fn with_capacity(n_guess:usize) -> Self {
EditGraph {
adj: FxHashMap::with_capacity_and_hasher(n_guess, Default::default()),
degs: FxHashMap::with_capacity_and_hasher(n_guess, Default::default()),
m :0
}
}
fn add_vertex(&mut self, u:&Vertex) -> bool {
if !self.adj.contains_key(u) {
self.adj.insert(*u, FxHashSet::default());
self.degs.insert(*u, 0);
true
} else {
false
}
}
fn add_edge(&mut self, u:&Vertex, v:&Vertex) -> bool {
self.add_vertex(u);
self.add_vertex(v);
if !self.adjacent(u, v) {
self.adj.get_mut(u).unwrap().insert(*v);
self.adj.get_mut(v).unwrap().insert(*u);
self.degs.insert(*u, self.degs[u] + 1);
self.degs.insert(*v, self.degs[v] + 1);
self.m += 1;
true
} else {
false
}
}
fn remove_edge(&mut self, u:&Vertex, v:&Vertex) -> bool {
if self.adjacent(u, v) {
self.adj.get_mut(u).unwrap().remove(v);
self.adj.get_mut(v).unwrap().remove(u);
self.degs.insert(*u, self.degs[u] - 1);
self.degs.insert(*v, self.degs[v] - 1);
self.m -= 1;
true
} else {
false
}
}
fn remove_vertex(&mut self, u:&Vertex) -> bool {
if !self.contains(u) {
false
} else {
let N = self.adj.get(u).unwrap().clone();
for v in &N {
self.adj.get_mut(v).unwrap().remove(u);
self.degs.insert(*v, self.degs[v] - 1);
self.m -= 1;
}
self.adj.remove(u);
self.degs.remove(u);
true
}
}
}
impl EditGraph {
pub fn path(n:u32) -> EditGraph {
let mut res = EditGraph::with_capacity(n as usize);
for u in 0..(n-1) {
let v = u+1;
res.add_edge(&u,&v);
}
res
}
pub fn cycle(n:u32) -> EditGraph {
let mut res = EditGraph::with_capacity(n as usize);
for u in 0..n {
let v = (u+1) % n;
res.add_edge(&u,&v);
}
res
}
pub fn matching(n:u32) -> EditGraph {
let mut res = EditGraph::with_capacity(n as usize);
for u in 0..n {
let v = u+n;
res.add_edge(&u,&v);
}
res
}
pub fn star(n:u32) -> EditGraph {
EditGraph::biclique(1, n)
}
pub fn clique(n:u32) -> EditGraph {
let mut res = EditGraph::with_capacity(n as usize);
for u in 0..n {
for v in (u+1)..n {
res.add_edge(&u,&v);
}
}
res
}
pub fn independent(n:u32) -> EditGraph {
let mut res = EditGraph::with_capacity(n as usize);
for u in 0..n {
res.add_vertex(&u);
}
res
}
pub fn biclique(s:u32, t:u32) -> EditGraph {
let mut res = EditGraph::with_capacity((s+t) as usize);
for u in 0..s {
for v in s..(s+t) {
res.add_edge(&u,&v);
}
}
res
}
pub fn complete_kpartite<'a, I>(sizes:I) -> EditGraph where I: IntoIterator<Item=&'a u32> {
let sizes:Vec<u32> = sizes.into_iter().cloned().collect();
if sizes.is_empty() {
return EditGraph::new();
} else if sizes.len() == 1 {
return EditGraph::clique(sizes[0]);
}
let mut ranges:Vec<(u32,u32)> = Vec::new();
let mut left = 0;
for size in sizes {
ranges.push((left, left+size));
left += size;
}
let n = ranges.last().unwrap().1;
let mut res = EditGraph::with_capacity(n as usize);
for i in 0..ranges.len() {
let (leftA,rightA) = ranges[i];
for j in (i+1)..ranges.len() {
let (leftB,rightB) = ranges[j];
for u in leftA..rightA {
for v in leftB..rightB {
res.add_edge(&u, &v);
}
}
}
}
res
}
pub fn disj_union(&self, graph: &impl Graph) -> EditGraph {
let mut res = EditGraph::with_capacity(self.len() + graph.len());
let offset:Vertex = self.vertices().max().map(|x| x+1).unwrap_or(0);
res.add_vertices(self.vertices().cloned());
res.add_edges(self.edges());
res.add_vertices(graph.vertices().map(|v| v+offset));
res.add_edges(graph.edges().map(|(u,v)| (u+offset,v+offset) ));
res
}
pub fn disj_unions<'a,I,G>(it: I) -> EditGraph where I: Iterator<Item = &'a G>, G: Graph + 'a {
let mut res = EditGraph::new();
for graph in it {
res = res.disj_union(graph);
}
res
}
pub fn normalize(&self) -> (EditGraph, FxHashMap<Vertex, Vertex>) {
let mut res = EditGraph::with_capacity(self.num_vertices());
let mut order:Vec<_> = self.vertices().collect();
order.sort_unstable();
let id2vex:FxHashMap<Vertex, Vertex> = order.iter()
.enumerate().map(|(i,v)| (i as Vertex, **v) )
.collect();
let vex2id:FxHashMap<Vertex, Vertex> = id2vex.iter()
.map(|(i,v)| (*v, *i))
.collect();
for u in self.vertices() {
res.add_vertex(&vex2id[u]);
}
for (u, v) in self.edges() {
res.add_edge(&vex2id[&u], &vex2id[&v]);
}
(res, id2vex)
}
pub fn contract<'a, I>(&mut self, mut vertices:I) -> Vertex where I: Iterator<Item=&'a Vertex> {
let u = vertices.next().unwrap();
self.contract_into(u, vertices);
*u
}
pub fn contract_pair(&mut self, u:&Vertex, v:&Vertex) {
if !self.contains(u) || !self.contains(v) {
panic!("Pair {u},{v} not contained in graph.");
}
let mut N:VertexSet = self.neighbours(v).cloned().collect();
N.remove(u);
for x in N {
self.add_edge(u, &x);
}
self.remove_vertex(v);
}
pub fn contract_into<'a, I>(&mut self, center:&Vertex, vertices:I) where I: Iterator<Item=&'a Vertex> {
let mut contract:VertexSet = vertices.cloned().collect();
contract.remove(center);
let mut N = self.neighbourhood(contract.iter());
N.remove(center);
for u in N {
self.add_edge(center, &u);
}
for v in contract {
self.remove_vertex(&v);
}
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::algorithms::GraphAlgorithms;
#[test]
fn components() {
let n:u32 = 10;
let G = EditGraph::matching(n);
assert_eq!(G.components().len(), G.edges().count());
assert_eq!(EditGraph::clique(5).components().len(), 1);
}
#[test]
fn disj_union() {
let mut G = EditGraph::matching(5);
G = G.disj_union(&EditGraph::matching(5));
assert_eq!(G.components().len(), G.edges().count());
assert_eq!(EditGraph::clique(2),
EditGraph::clique(2).disj_union(&EditGraph::new()) );
assert_eq!(EditGraph::clique(2),
EditGraph::new().disj_union(&EditGraph::clique(2)) );
let H1 = EditGraph::clique(5);
let H2 = EditGraph::clique(6);
assert_eq!(H1.disj_union(&H2),
EditGraph::disj_unions(vec![H1,H2].iter()));
}
#[test]
fn neighbourhoods() {
let mut G = EditGraph::new();
G.add_edge(&0, &1);
G.add_edge(&1, &2);
G.add_edge(&2, &3);
G.add_edge(&3, &4);
assert_eq!( G.neighbourhood([2].iter()), [1,3].iter().cloned().collect());
assert_eq!( G.neighbourhood([1,2].iter()), [0,3].iter().cloned().collect());
assert_eq!( G.neighbourhood([1,3].iter()), [0,2,4].iter().cloned().collect());
}
#[test]
fn equality() {
let mut G = EditGraph::new();
G.add_edge(&0, &1);
G.add_edge(&1, &2);
G.add_edge(&2, &3);
G.add_edge(&3, &0);
let mut H = G.subgraph([0,1,2,3].iter());
assert_eq!(G, H);
H.add_edge(&0, &2);
assert_ne!(G, H);
H.remove_edge(&0, &2);
assert_eq!(G, H);
}
#[test]
fn isolates_and_loops() {
let mut G = EditGraph::new();
G.add_edge(&0, &1);
G.add_edge(&0, &0);
G.add_edge(&2, &2);
assert_eq!(G.num_vertices(), 3);
assert_eq!(G.num_edges(), 3);
G.remove_loops();
assert_eq!(G.num_vertices(), 3);
assert_eq!(G.num_edges(), 1);
G.remove_isolates();
assert_eq!(G.num_vertices(), 2);
assert_eq!(G.num_edges(), 1);
G.remove_edge(&0, &1);
G.remove_isolates();
assert_eq!(G, EditGraph::new());
}
#[test]
fn N_iteration() {
let mut G = EditGraph::new();
G.add_edge(&0, &1);
G.add_edge(&0, &2);
G.add_edge(&0, &3);
G.add_edge(&0, &4);
G.add_edge(&0, &5);
for (v,N) in G.neighbourhoods() {
if v == 0 {
assert_eq!(N.cloned().collect::<VertexSet>(), [1,2,3,4,5].iter().cloned().collect());
} else {
assert_eq!(N.cloned().collect::<VertexSet>(), [0].iter().cloned().collect());
}
}
}
#[test]
fn edge_iteration() {
let mut G = EditGraph::new();
G.add_edge(&0, &1);
G.add_edge(&0, &2);
G.add_edge(&0, &3);
G.add_edge(&0, &4);
G.add_edge(&0, &5);
for e in G.edges() {
println!("{:?}", e);
}
assert_eq!(G.edges().count(), 5);
}
#[test]
fn basic_operations() {
let mut G = EditGraph::new();
G.add_vertex(&0);
G.add_vertex(&1);
G.add_vertex(&2);
assert_eq!(G.num_edges(), 0);
G.add_edge(&0, &1);
assert_eq!(G.degree(&0), 1);
assert_eq!(G.degree(&1), 1);
assert_eq!(G.degree(&2), 0);
assert_eq!(G.num_vertices(), 3);
assert_eq!(G.num_edges(), 1);
G.remove_edge(&0, &1);
assert_eq!(G.degree(&0), 0);
assert_eq!(G.degree(&1), 0);
assert_eq!(G.num_edges(), 0);
G.add_edge(&0, &1);
G.add_edge(&0, &2);
G.add_edge(&1, &2);
assert_eq!(G.degree(&0), 2);
assert_eq!(G.num_edges(), 3);
G.remove_vertex(&2);
assert_eq!(G.degree(&0), 1);
assert_eq!(G.num_vertices(), 2);
assert_eq!(G.num_edges(), 1);
G.remove_vertex(&1);
assert_eq!(G.degree(&0), 0);
assert_eq!(G.num_vertices(), 1);
assert_eq!(G.num_edges(), 0);
G.remove_vertex(&0);
assert_eq!(G.num_vertices(), 0);
assert_eq!(G.num_edges(), 0);
}
#[test]
fn contract_pair() {
let mut G = EditGraph::new();
G.add_edge(&0, &1);
G.add_edge(&1, &2);
G.add_edge(&2, &3);
G.contract_pair(&1, &2);
assert!(G.contains(&1));
assert!(!G.contains(&2));
assert_eq!(G.neighbours(&1).collect::<VertexSetRef>(),
[0,3].iter().collect());
}
#[test]
fn contract() {
let mut G = EditGraph::new();
G.add_edge(&0, &1);
G.add_edge(&1, &2);
G.add_edge(&2, &0);
G.add_edge(&0, &3);
G.add_edge(&1, &4);
G.add_edge(&2, &5);
{
let mut H = G.clone();
H.contract_into(&0, [0, 1, 2].iter());
assert_eq!(H.num_vertices(), 4);
assert_eq!(H.vertices().collect::<VertexSetRef>(),
[0,3,4,5].iter().collect());
let mut HH = G.clone();
HH.contract([0, 1, 2].iter()); assert_eq!(H, HH);
}
{
let mut H = G.clone();
H.contract_into(&0, [0, 1].iter());
assert_eq!(H.num_vertices(), 5);
assert_eq!(H.neighbours(&0).collect::<VertexSetRef>(),
[2,3,4].iter().collect());
assert_eq!(H.vertices().collect::<VertexSetRef>(),
[0,2,3,4,5].iter().collect());
}
}
}