use crate::{traits::*, GraphErrors, GenericGraph};
use std::marker::PhantomData;
use std::convert::From;
#[cfg(feature = "serde_support")]
use serde::{Serialize, Deserialize};
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
pub struct NodeContainer<T: Node>{
id: usize,
pub(crate) adj: Vec<usize>,
node: T,
}
impl<T: Node + SerdeStateConform> AdjContainer<T> for NodeContainer<T> {
fn new(id: usize, node: T) -> Self {
NodeContainer{
id,
adj: Vec::new(),
node,
}
}
fn contained(&self) -> &T {
&self.node
}
fn contained_mut(&mut self) -> &mut T {
&mut self.node
}
fn neighbors(&self) -> IterWrapper {
IterWrapper::new_generic(self.adj.iter())
}
fn degree(&self) -> usize {
self.adj.len()
}
fn id(&self) -> usize {
self.id
}
fn is_adjacent(&self, other_id: usize) -> bool {
self.adj.contains(&other_id)
}
fn sort_adj(&mut self) {
self.adj.sort_unstable();
}
#[doc(hidden)]
unsafe fn clear_edges(&mut self) {
self.adj.clear();
}
#[doc(hidden)]
unsafe fn push(&mut self, other: &mut Self)
-> Result<(), GraphErrors>
{
if self.is_adjacent(other.id()) {
return Err(GraphErrors::EdgeExists);
}
self.adj.push(other.id());
other.adj.push(self.id);
Ok(())
}
#[doc(hidden)]
unsafe fn remove(&mut self, other: &mut Self)
-> Result<(), GraphErrors>
{
if !self.is_adjacent(other.id()){
return Err(GraphErrors::EdgeDoesNotExist);
}
self.swap_remove_element(other.id());
other.swap_remove_element(self.id());
Ok(())
}
fn get_adj_first(&self) -> Option<&usize> {
self.adj.first()
}
}
impl<T: Node> NodeContainer<T> {
fn swap_remove_element(&mut self, elem: usize) {
let index = self.adj
.iter()
.position(|&x| x == elem)
.expect("swap_remove_element ERROR 0");
self.adj
.swap_remove(index);
}
}
pub type Graph<T> = GenericGraph<T, NodeContainer<T>>;
impl<T> Graph<T>
where T: Node
{
pub fn complete_graph(n: usize) -> Self
{
let mut vertices = Vec::with_capacity(n);
for i in 0..n {
let mut adj = Vec::with_capacity(n - 1);
adj.extend(0..i);
adj.extend((i+1)..n);
vertices.push(
NodeContainer{
id: i,
node: T::new_from_index(i),
adj,
}
)
}
Self{
next_id: n,
edge_count: n*(n - 1) / 2,
vertices,
phantom: PhantomData::<T>,
}
}
pub(crate) fn reset_from_graph(&mut self, other: &Self)
{
assert!(other.vertex_count() <= self.vertex_count());
self.clear_edges();
for i in 0..other.vertex_count(){
self.vertices[i].adj.extend_from_slice(other.vertices[i].adj.as_slice());
}
self.edge_count = other.edge_count;
}
}
impl<T: Node, A: AdjContainer<T>> From<&GenericGraph<T, A>> for Graph<T>
{
fn from(source: &GenericGraph<T, A>) -> Self
{
let vertices = source
.container_iter()
.map(|container|
NodeContainer{
id: container.id(),
node: container.contained().clone(),
adj: container.neighbors().copied().collect(),
}
).collect();
Self{
next_id: source.next_id,
edge_count: source.edge_count(),
vertices,
phantom: PhantomData::<T>,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::EmptyNode;
#[test]
fn test_graph_container_push() {
let mut c = NodeContainer::new(0, EmptyNode::new_from_index(0));
let mut c2 = NodeContainer::new(1, EmptyNode::new_from_index(1));
let res = unsafe { c.push(&mut c2) };
if let Err(e) = res {
panic!("error: {}", e);
}
let res = unsafe { c.push(&mut c2) };
assert!(res.is_err());
assert_eq!(0, c.id());
}
#[test]
fn correct_complete_graphs() {
let g = Graph::<EmptyNode>::complete_graph(50);
for index in 0..50 {
let container = g.container(index);
for neigbor in 0..50 {
if neigbor == index {
assert!(!container.is_adjacent(neigbor));
} else {
assert!(container.is_adjacent(neigbor));
}
}
}
assert_eq!(g.vertex_count(), 50);
}
}