fera_graph/graphs/
adjset.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5use prelude::*;
6use props::HashMapProp;
7
8use std::cmp::Ordering;
9use std::collections::{hash_map, hash_set, HashMap, HashSet};
10use std::hash::{Hash, Hasher};
11use std::iter::Cloned;
12use std::marker::PhantomData;
13
14pub type AdjSetGraph<V> = AdjSet<V, Undirected>;
15pub type AdjSetDigraph<V> = AdjSet<V, Directed>;
16
17type HashMapAdj<K, V> = HashMap<K, V>;
18type HashSetAdj<K> = HashSet<K>;
19
20pub struct AdjSet<V: AdjSetVertex, K: AdjSetEdgeKind<V>> {
21    adj: HashMapAdj<V, HashSetAdj<V>>,
22    num_edges: usize,
23    _marker: PhantomData<K>,
24}
25
26impl<V, K> Default for AdjSet<V, K>
27where
28    V: AdjSetVertex,
29    K: AdjSetEdgeKind<V>,
30{
31    fn default() -> Self {
32        Self::new()
33    }
34}
35
36pub trait AdjSetEdgeKind<V: AdjSetVertex>: UniformEdgeKind {
37    type Edge: AdjSetEdge<V>;
38}
39
40pub trait AdjSetVertex: 'static + GraphItem + PartialOrd {}
41
42impl<V: 'static + GraphItem + PartialOrd> AdjSetVertex for V {}
43
44pub trait AdjSetEdge<V>: 'static + GraphItem
45where
46    V: AdjSetVertex,
47{
48    fn new(u: V, v: V) -> Self;
49
50    fn source(&self) -> V;
51
52    fn target(&self) -> V;
53}
54
55// Undirected
56
57#[derive(Copy, Clone, Eq, Debug)]
58pub struct UndirectedEdge<V>(V, V);
59
60impl<V: PartialEq> PartialEq for UndirectedEdge<V> {
61    fn eq(&self, other: &Self) -> bool {
62        self.0 == other.0 && self.1 == other.1 || self.1 == other.0 && self.0 == other.1
63    }
64}
65
66impl<V: PartialEq> PartialEq<(V, V)> for UndirectedEdge<V> {
67    fn eq(&self, other: &(V, V)) -> bool {
68        self.0 == other.0 && self.1 == other.1 || self.1 == other.0 && self.0 == other.1
69    }
70}
71
72impl<V: Ord> PartialOrd for UndirectedEdge<V> {
73    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
74        let r = if self.0 <= self.1 {
75            if other.0 <= other.1 {
76                self.0.cmp(&other.0).then_with(|| self.1.cmp(&other.1))
77            } else {
78                self.0.cmp(&other.1).then_with(|| self.1.cmp(&other.0))
79            }
80        } else if other.0 <= other.1 {
81            self.1.cmp(&other.0).then_with(|| self.0.cmp(&other.1))
82        } else {
83            self.1.cmp(&other.1).then_with(|| self.0.cmp(&other.0))
84        };
85        Some(r)
86    }
87}
88
89impl<V: Ord> Ord for UndirectedEdge<V> {
90    fn cmp(&self, other: &Self) -> Ordering {
91        self.partial_cmp(other).unwrap()
92    }
93}
94
95impl<V: PartialOrd + Hash> Hash for UndirectedEdge<V> {
96    fn hash<H: Hasher>(&self, state: &mut H) {
97        if self.0 < self.1 {
98            self.0.hash(state);
99            self.1.hash(state);
100        } else {
101            self.1.hash(state);
102            self.0.hash(state);
103        }
104    }
105}
106
107impl<V> AdjSetEdge<V> for UndirectedEdge<V>
108where
109    V: AdjSetVertex + PartialOrd,
110{
111    fn new(u: V, v: V) -> Self {
112        UndirectedEdge(u, v)
113    }
114
115    fn source(&self) -> V {
116        self.0
117    }
118
119    fn target(&self) -> V {
120        self.1
121    }
122}
123
124impl<V> AdjSetEdgeKind<V> for Undirected
125where
126    V: AdjSetVertex + PartialOrd,
127{
128    type Edge = UndirectedEdge<V>;
129}
130
131// Directed
132
133pub type DirectedEdge<V> = (V, V);
134
135impl<V> AdjSetEdge<V> for DirectedEdge<V>
136where
137    V: AdjSetVertex,
138{
139    fn new(u: V, v: V) -> Self {
140        (u, v)
141    }
142
143    fn source(&self) -> V {
144        self.0
145    }
146
147    fn target(&self) -> V {
148        self.1
149    }
150}
151
152impl<V> AdjSetEdgeKind<V> for Directed
153where
154    V: AdjSetVertex,
155{
156    type Edge = DirectedEdge<V>;
157}
158
159// Graph traits implementation
160
161impl<'a, V, K> VertexTypes<'a, AdjSet<V, K>> for AdjSet<V, K>
162where
163    V: AdjSetVertex,
164    K: AdjSetEdgeKind<V>,
165{
166    type VertexIter = Cloned<hash_map::Keys<'a, V, HashSetAdj<V>>>;
167    type OutNeighborIter = Cloned<hash_set::Iter<'a, V>>;
168}
169
170impl<V, K> WithVertex for AdjSet<V, K>
171where
172    V: AdjSetVertex,
173    K: AdjSetEdgeKind<V>,
174{
175    type Vertex = V;
176    type OptionVertex = Option<V>;
177}
178
179impl<'a, V, K> EdgeTypes<'a, AdjSet<V, K>> for AdjSet<V, K>
180where
181    V: AdjSetVertex,
182    K: AdjSetEdgeKind<V>,
183{
184    type EdgeIter = Edges<'a, V, K>;
185    type OutEdgeIter = OutEdges<'a, V, K>;
186}
187
188impl<V, K> WithEdge for AdjSet<V, K>
189where
190    V: AdjSetVertex,
191    K: AdjSetEdgeKind<V>,
192{
193    type Kind = K;
194    type Edge = K::Edge;
195    type OptionEdge = Option<K::Edge>;
196
197    fn source(&self, e: Edge<Self>) -> Vertex<Self> {
198        e.source()
199    }
200
201    fn target(&self, e: Edge<Self>) -> Vertex<Self> {
202        e.target()
203    }
204
205    fn orientation(&self, _e: Edge<Self>) -> Orientation {
206        K::orientation()
207    }
208
209    fn get_reverse(&self, e: Edge<Self>) -> Option<Edge<Self>> {
210        Some(K::Edge::new(e.target(), e.source()))
211    }
212}
213
214impl<V, K> VertexList for AdjSet<V, K>
215where
216    V: AdjSetVertex,
217    K: AdjSetEdgeKind<V>,
218{
219    fn vertices(&self) -> VertexIter<Self> {
220        self.adj.keys().cloned()
221    }
222
223    fn num_vertices(&self) -> usize {
224        self.adj.len()
225    }
226}
227
228impl<V, K> EdgeList for AdjSet<V, K>
229where
230    V: AdjSetVertex,
231    K: AdjSetEdgeKind<V>,
232{
233    fn edges(&self) -> EdgeIter<Self> {
234        Edges {
235            iter: self.adj.iter(),
236            inner: None,
237            _marker: PhantomData,
238        }
239    }
240
241    fn num_edges(&self) -> usize {
242        self.num_edges
243    }
244
245    fn get_edge_by_ends(&self, u: Vertex<Self>, v: Vertex<Self>) -> Option<Edge<Self>> {
246        self.adj
247            .get(&u)
248            .and_then(|adj| adj.get(&v))
249            .and_then(|_| Some(K::Edge::new(u, v)))
250    }
251}
252
253impl<V, K> Adjacency for AdjSet<V, K>
254where
255    V: AdjSetVertex,
256    K: AdjSetEdgeKind<V>,
257{
258    fn out_neighbors(&self, v: Vertex<Self>) -> OutNeighborIter<Self> {
259        self.out_neighbors_(v).iter().cloned()
260    }
261
262    fn out_degree(&self, v: Vertex<Self>) -> usize {
263        self.out_neighbors_(v).len()
264    }
265}
266
267impl<V, K> Incidence for AdjSet<V, K>
268where
269    V: AdjSetVertex,
270    K: AdjSetEdgeKind<V>,
271{
272    fn out_edges(&self, v: Vertex<Self>) -> OutEdgeIter<Self> {
273        OutEdges {
274            source: v,
275            adj: self.out_neighbors_(v).iter(),
276            _marker: PhantomData,
277        }
278    }
279}
280
281impl<V, K> AdjSet<V, K>
282where
283    V: AdjSetVertex,
284    K: AdjSetEdgeKind<V>,
285{
286    pub fn new() -> Self {
287        AdjSet {
288            adj: Default::default(),
289            num_edges: 0,
290            _marker: PhantomData,
291        }
292    }
293
294    pub fn add_vertex(&mut self, v: V) {
295        self.adj.entry(v).or_insert_with(Default::default);
296    }
297
298    pub fn add_edge(&mut self, u: V, v: V) -> K::Edge {
299        if self.get_edge_by_ends(u, v).is_some() {
300            panic!("Multiedge not supported");
301        }
302
303        // insert u and (u, v)
304        self.adj.entry(u).or_insert_with(Default::default).insert(v);
305
306        // insert v
307        let entry = self.adj.entry(v).or_insert_with(Default::default);
308
309        if K::is_undirected() {
310            // insert (v, u)
311            entry.insert(u);
312        }
313
314        self.num_edges += 1;
315
316        K::Edge::new(u, v)
317    }
318
319    fn out_neighbors_(&self, v: Vertex<Self>) -> &HashSetAdj<V> {
320        self.adj
321            .get(&v)
322            .unwrap_or_else(|| panic!("{:?} is not a valid vertex", v))
323    }
324}
325
326// Props
327
328impl<V, K, T> WithVertexProp<T> for AdjSet<V, K>
329where
330    V: AdjSetVertex,
331    K: AdjSetEdgeKind<V>,
332    T: Clone,
333{
334    type VertexProp = HashMapProp<V, T>;
335}
336
337impl<V, K, T> WithEdgeProp<T> for AdjSet<V, K>
338where
339    V: AdjSetVertex,
340    K: AdjSetEdgeKind<V>,
341    T: Clone,
342{
343    type EdgeProp = HashMapProp<K::Edge, T>;
344}
345
346// Iterators
347
348pub struct Edges<'a, V, K>
349where
350    V: AdjSetVertex,
351    K: AdjSetEdgeKind<V>,
352{
353    iter: hash_map::Iter<'a, V, HashSetAdj<V>>,
354    inner: Option<(V, hash_set::Iter<'a, V>)>,
355    _marker: PhantomData<K>,
356}
357
358impl<'a, V, K> Iterator for Edges<'a, V, K>
359where
360    V: AdjSetVertex,
361    K: AdjSetEdgeKind<V>,
362{
363    type Item = K::Edge;
364
365    fn next(&mut self) -> Option<Self::Item> {
366        loop {
367            if let Some((source, ref mut inner)) = self.inner {
368                if let Some(target) = inner.next() {
369                    if K::is_undirected() && source > *target {
370                        continue;
371                    }
372                    return Some(K::Edge::new(source, *target));
373                }
374            }
375
376            if let Some((source, inner)) = self.iter.next() {
377                self.inner = Some((*source, inner.iter()));
378            } else {
379                return None;
380            }
381        }
382    }
383
384    // TODO: implements size_hint and ExactSizeIterator
385}
386
387pub struct OutEdges<'a, V, K>
388where
389    V: AdjSetVertex,
390    K: AdjSetEdgeKind<V>,
391{
392    source: V,
393    adj: hash_set::Iter<'a, V>,
394    _marker: PhantomData<K>,
395}
396
397impl<'a, V, K> Iterator for OutEdges<'a, V, K>
398where
399    V: AdjSetVertex,
400    K: AdjSetEdgeKind<V>,
401{
402    type Item = K::Edge;
403
404    fn next(&mut self) -> Option<Self::Item> {
405        let source = self.source;
406        self.adj.next().map(|target| K::Edge::new(source, *target))
407    }
408
409    fn size_hint(&self) -> (usize, Option<usize>) {
410        self.adj.size_hint()
411    }
412}
413
414impl<'a, V, K> ExactSizeIterator for OutEdges<'a, V, K>
415where
416    V: AdjSetVertex,
417    K: AdjSetEdgeKind<V>,
418{
419    fn len(&self) -> usize {
420        self.adj.len()
421    }
422}
423
424#[cfg(test)]
425mod tests {
426    pub use super::*;
427    pub use fera_fun::vec;
428    pub use prelude::*;
429    pub use tests::GraphTests;
430
431    pub fn sorted<T: Clone + Ord>(xs: &[T]) -> Vec<T> {
432        let mut v = xs.to_vec();
433        v.sort();
434        v
435    }
436
437    mod undirected {
438        use super::*;
439        struct Test;
440
441        impl GraphTests for Test {
442            type G = AdjSetGraph<u32>;
443
444            fn new() -> (Self::G, Vec<Vertex<Self::G>>, Vec<Edge<Self::G>>) {
445                let e = UndirectedEdge::new;
446                let mut g = AdjSet::new();
447                g.add_edge(1, 2);
448                g.add_edge(3, 4);
449                g.add_edge(4, 1);
450                g.add_edge(7, 4);
451                let v = vec(g.vertices());
452                let ee = vec(g.edges());
453                assert_eq!(sorted(&v), vec![1, 2, 3, 4, 7]);
454                assert_eq!(sorted(&ee), vec![e(1, 2), e(1, 4), e(3, 4), e(4, 7)]);
455                (g, v, ee)
456            }
457        }
458
459        graph_tests!{Test}
460    }
461
462    mod directed {
463        use super::*;
464        struct Test;
465
466        impl GraphTests for Test {
467            type G = AdjSetDigraph<u32>;
468
469            fn new() -> (Self::G, Vec<Vertex<Self::G>>, Vec<Edge<Self::G>>) {
470                let mut g = AdjSet::new();
471                g.add_edge(1, 2);
472                g.add_edge(3, 4);
473                g.add_edge(4, 1);
474                g.add_edge(7, 4);
475                let v = vec(g.vertices());
476                let ee = vec(g.edges());
477                assert_eq!(sorted(&v), vec![1, 2, 3, 4, 7]);
478                assert_eq!(sorted(&ee), vec![(1, 2), (3, 4), (4, 1), (7, 4)]);
479                (g, v, ee)
480            }
481        }
482
483        graph_tests!{Test}
484    }
485}