use std::marker;
use std::collections::{
HashSet,
BitSet,
VecDeque,
};
use std::hash::Hash;
use super::{
graphmap,
graph,
EdgeType,
EdgeDirection,
Graph,
GraphMap,
};
use graph::{
IndexType,
};
pub trait Graphlike : marker::MarkerTrait {
type NodeId: Clone;
}
pub trait NeighborIter<'a> : Graphlike{
type Iter: Iterator<Item=Self::NodeId>;
fn neighbors(&'a self, n: Self::NodeId) -> Self::Iter;
}
impl<'a, N, E, Ty, Ix> NeighborIter<'a> for Graph<N, E, Ty, Ix> where
Ty: EdgeType,
Ix: IndexType,
{
type Iter = graph::Neighbors<'a, E, Ix>;
fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
{
Graph::neighbors(self, n)
}
}
impl<'a, N, E> NeighborIter<'a> for GraphMap<N, E>
where N: Copy + Clone + Ord + Hash + Eq
{
type Iter = graphmap::Neighbors<'a, N>;
fn neighbors(&'a self, n: N) -> graphmap::Neighbors<'a, N>
{
GraphMap::neighbors(self, n)
}
}
pub struct AsUndirected<G>(pub G);
pub struct Reversed<G>(pub G);
impl<'a, 'b, N, E, Ty, Ix> NeighborIter<'a> for AsUndirected<&'b Graph<N, E, Ty, Ix>> where
Ty: EdgeType,
Ix: IndexType,
{
type Iter = graph::Neighbors<'a, E, Ix>;
fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
{
Graph::neighbors_undirected(self.0, n)
}
}
impl<'a, 'b, N, E, Ty, Ix> NeighborIter<'a> for Reversed<&'b Graph<N, E, Ty, Ix>> where
Ty: EdgeType,
Ix: IndexType,
{
type Iter = graph::Neighbors<'a, E, Ix>;
fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
{
Graph::neighbors_directed(self.0, n, EdgeDirection::Incoming)
}
}
pub trait VisitMap<N> {
fn visit(&mut self, N) -> bool;
fn is_visited(&self, &N) -> bool;
}
impl<Ix> VisitMap<graph::NodeIndex<Ix>> for BitSet where
Ix: IndexType,
{
fn visit(&mut self, x: graph::NodeIndex<Ix>) -> bool {
self.insert(x.index())
}
fn is_visited(&self, x: &graph::NodeIndex<Ix>) -> bool {
self.contains(&x.index())
}
}
impl<N: Eq + Hash> VisitMap<N> for HashSet<N> {
fn visit(&mut self, x: N) -> bool {
self.insert(x)
}
fn is_visited(&self, x: &N) -> bool {
self.contains(x)
}
}
pub trait Visitable : Graphlike {
type Map: VisitMap<<Self as Graphlike>::NodeId>;
fn visit_map(&self) -> Self::Map;
}
impl<N, E, Ty, Ix> Graphlike for Graph<N, E, Ty, Ix> where
Ix: IndexType,
{
type NodeId = graph::NodeIndex<Ix>;
}
impl<N, E, Ty, Ix> Visitable for Graph<N, E, Ty, Ix> where
Ty: EdgeType,
Ix: IndexType,
{
type Map = BitSet;
fn visit_map(&self) -> BitSet { BitSet::with_capacity(self.node_count()) }
}
impl<N: Clone, E> Graphlike for GraphMap<N, E>
{
type NodeId = N;
}
impl<N, E> Visitable for GraphMap<N, E>
where N: Copy + Clone + Ord + Eq + Hash
{
type Map = HashSet<N>;
fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}
impl<'a, V: Graphlike> Graphlike for AsUndirected<&'a V>
{
type NodeId = <V as Graphlike>::NodeId;
}
impl<'a, V: Graphlike> Graphlike for Reversed<&'a V>
{
type NodeId = <V as Graphlike>::NodeId;
}
impl<'a, V: Visitable> Visitable for AsUndirected<&'a V>
{
type Map = <V as Visitable>::Map;
fn visit_map(&self) -> <V as Visitable>::Map {
self.0.visit_map()
}
}
impl<'a, V: Visitable> Visitable for Reversed<&'a V>
{
type Map = <V as Visitable>::Map;
fn visit_map(&self) -> <V as Visitable>::Map {
self.0.visit_map()
}
}
pub trait GetAdjacencyMatrix : Graphlike {
type AdjMatrix;
fn adjacency_matrix(&self) -> Self::AdjMatrix;
fn is_adjacent(&self, matrix: &Self::AdjMatrix, a: Self::NodeId, b: Self::NodeId) -> bool;
}
impl<N, E> GetAdjacencyMatrix for GraphMap<N, E>
where N: Copy + Clone + Ord + Eq + Hash
{
type AdjMatrix = ();
#[inline]
fn adjacency_matrix(&self) { }
#[inline]
fn is_adjacent(&self, _: &(), a: N, b: N) -> bool {
self.contains_edge(a, b)
}
}
#[derive(Clone, Debug)]
pub struct Dfs<N, VM> {
pub stack: Vec<N>,
pub discovered: VM,
}
impl<G: Visitable> Dfs<G::NodeId, G::Map>
{
pub fn new(graph: &G, start: G::NodeId) -> Self
{
let mut dfs = Dfs::empty(graph);
dfs.move_to(start);
dfs
}
pub fn empty(graph: &G) -> Self
{
Dfs {
stack: Vec::new(),
discovered: graph.visit_map(),
}
}
}
impl<N, VM> Dfs<N, VM> where
N: Clone,
VM: VisitMap<N>
{
pub fn move_to(&mut self, start: N)
{
self.discovered.visit(start.clone());
self.stack.clear();
self.stack.push(start);
}
}
impl<N, VM> Dfs<N, VM> where
N: Clone,
VM: VisitMap<N>
{
pub fn next<'a, G>(&mut self, graph: &'a G) -> Option<N> where
G: Graphlike<NodeId=N>,
G: for<'b> NeighborIter<'b>,
{
while let Some(node) = self.stack.pop() {
for succ in graph.neighbors(node.clone()) {
if self.discovered.visit(succ.clone()) {
self.stack.push(succ);
}
}
return Some(node);
}
None
}
}
#[derive(Clone)]
pub struct Bfs<N, VM> {
pub stack: VecDeque<N>,
pub discovered: VM,
}
impl<G: Visitable> Bfs<G::NodeId, <G as Visitable>::Map> where
G::NodeId: Clone,
{
pub fn new(graph: &G, start: G::NodeId) -> Self
{
let mut discovered = graph.visit_map();
discovered.visit(start.clone());
let mut stack = VecDeque::new();
stack.push_front(start.clone());
Bfs {
stack: stack,
discovered: discovered,
}
}
}
impl<N, VM> Bfs<N, VM> where
N: Clone,
VM: VisitMap<N>
{
pub fn next<'a, G>(&mut self, graph: &'a G) -> Option<N> where
G: Graphlike<NodeId=N>,
G: for<'b> NeighborIter<'b>,
{
while let Some(node) = self.stack.pop_front() {
for succ in graph.neighbors(node.clone()) {
if self.discovered.visit(succ.clone()) {
self.stack.push_back(succ);
}
}
return Some(node);
}
None
}
}