rs_graph/
vecgraph.rs

1/*
2 * Copyright (c) 2021, 2022 Frank Fischer <frank-fischer@shadow-soft.de>
3 *
4 * This program is free software: you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation, either version 3 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program.  If not, see  <http://www.gnu.org/licenses/>
16 */
17
18use crate::builder::{Buildable, Builder};
19use crate::traits::{Directed, DirectedEdge, FiniteDigraph, FiniteGraph, GraphIterator, GraphType, Undirected};
20use crate::traits::{IndexGraph, Indexable};
21
22use crate::num::iter::{range, range_step, Range, RangeStep};
23use crate::num::traits::{PrimInt, Unsigned};
24
25use std::fmt;
26use std::hash::{Hash, Hasher};
27use std::slice::Iter as SliceIter;
28
29#[cfg(feature = "serialize")]
30use serde_derive::{Deserialize, Serialize};
31
32/// Node of a vector graph.
33///
34/// This is basically a newtype of the node index.
35#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
36pub struct Node<ID = u32>(ID)
37where
38    ID: PrimInt + Unsigned;
39
40impl<ID> fmt::Display for Node<ID>
41where
42    ID: PrimInt + Unsigned + fmt::Display,
43{
44    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
45        write!(f, "{}", self.0)
46    }
47}
48
49impl<ID> Indexable for Node<ID>
50where
51    ID: PrimInt + Unsigned,
52{
53    fn index(&self) -> usize {
54        self.0.to_usize().unwrap()
55    }
56}
57
58/// Edge of a vector graph.
59///
60/// This is basically a newtype of the *edge* index. Note that
61/// `e == g.reverse(e)`.
62#[derive(Eq, Clone, Copy, Debug)]
63pub struct Edge<ID = u32>(ID)
64where
65    ID: PrimInt + Unsigned;
66
67impl<ID> PartialEq for Edge<ID>
68where
69    ID: PrimInt + Unsigned,
70{
71    fn eq(&self, other: &Self) -> bool {
72        (self.0 >> 1) == (other.0 >> 1)
73    }
74}
75
76impl<ID> fmt::Display for Edge<ID>
77where
78    ID: PrimInt + Unsigned + fmt::Display,
79{
80    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
81        write!(
82            f,
83            "{}{}",
84            if (self.0 & ID::one()).is_zero() { "+" } else { "-" },
85            self.0 >> 1
86        )
87    }
88}
89
90impl<ID> Hash for Edge<ID>
91where
92    ID: PrimInt + Unsigned + Hash,
93{
94    fn hash<H: Hasher>(&self, state: &mut H) {
95        (self.0 >> 1).hash(state)
96    }
97}
98
99impl<ID> Indexable for Edge<ID>
100where
101    ID: PrimInt + Unsigned,
102{
103    fn index(&self) -> usize {
104        (self.0 >> 1).to_usize().unwrap()
105    }
106}
107
108impl<ID> DirectedEdge for Edge<ID>
109where
110    ID: PrimInt + Unsigned,
111{
112    type Edge = Self;
113
114    fn is_incoming(&self) -> bool {
115        !(self.0 & ID::one()).is_zero()
116    }
117
118    fn edge(&self) -> Self::Edge {
119        *self
120    }
121}
122
123/// Data for a node in a vector graph.
124#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
125struct NodeData<ID> {
126    firstout: ID,
127    firstin: ID,
128}
129
130/// Data for an edge in a vector graph.
131#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
132struct EdgeData<ID> {
133    nodes: [ID; 2],
134}
135
136/// A vector based graph data structure.
137#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
138pub struct VecGraph<ID = u32> {
139    nodes: Vec<NodeData<ID>>,
140    edges: Vec<EdgeData<ID>>,
141    // The list of adjacencies. This list contains the edge numbers in
142    // a specific order, so that for each node the incident outgoing
143    // and incoming edges are in successive positions.
144    adj: Vec<ID>,
145}
146
147/// A graph iterator over all nodes of a linked list graph.
148#[derive(Clone)]
149pub struct NodeIt<ID>(Range<ID>);
150
151impl<'a, ID> GraphIterator<VecGraph<ID>> for NodeIt<ID>
152where
153    ID: 'a + PrimInt + Unsigned,
154{
155    type Item = Node<ID>;
156
157    fn next(&mut self, _g: &VecGraph<ID>) -> Option<Self::Item> {
158        Iterator::next(&mut self.0).map(Node)
159    }
160
161    fn size_hint(&self, _g: &VecGraph<ID>) -> (usize, Option<usize>) {
162        Iterator::size_hint(&self.0)
163    }
164
165    fn count(self, _g: &VecGraph<ID>) -> usize {
166        Iterator::count(self.0)
167    }
168}
169
170/// An iterator over all edges of a linked list graph.
171///
172/// This iterator only returns the forward edges.
173#[derive(Clone)]
174pub struct EdgeIt<ID>(RangeStep<ID>);
175
176impl<'a, ID> GraphIterator<VecGraph<ID>> for EdgeIt<ID>
177where
178    ID: 'a + PrimInt + Unsigned,
179{
180    type Item = Edge<ID>;
181
182    fn next(&mut self, _g: &VecGraph<ID>) -> Option<Self::Item> {
183        Iterator::next(&mut self.0).map(Edge)
184    }
185
186    fn size_hint(&self, _g: &VecGraph<ID>) -> (usize, Option<usize>) {
187        Iterator::size_hint(&self.0)
188    }
189
190    fn count(self, _g: &VecGraph<ID>) -> usize {
191        Iterator::count(self.0)
192    }
193}
194
195impl<ID> GraphType for VecGraph<ID>
196where
197    ID: PrimInt + Unsigned,
198{
199    type Node<'a> = Node<ID>;
200    type Edge<'a> = Edge<ID>;
201}
202
203impl<ID> FiniteGraph for VecGraph<ID>
204where
205    ID: PrimInt + Unsigned,
206{
207    type NodeIt<'a> = NodeIt<ID>
208    where
209        ID: 'a;
210    type EdgeIt<'a> = EdgeIt<ID>
211    where
212        ID: 'a;
213
214    fn num_nodes(&self) -> usize {
215        self.nodes.len()
216    }
217
218    fn num_edges(&self) -> usize {
219        self.edges.len()
220    }
221
222    fn nodes_iter(&self) -> Self::NodeIt<'_> {
223        NodeIt(range(ID::zero(), ID::from(self.num_nodes()).unwrap()))
224    }
225
226    fn edges_iter(&self) -> Self::EdgeIt<'_> {
227        EdgeIt(range_step(
228            ID::zero(),
229            ID::from(2 * self.edges.len()).unwrap(),
230            ID::from(2).unwrap(),
231        ))
232    }
233
234    fn enodes(&self, e: Self::Edge<'_>) -> (Self::Node<'_>, Self::Node<'_>) {
235        let eid = e.index();
236        (Node(self.edges[eid].nodes[0]), Node(self.edges[eid].nodes[1]))
237    }
238}
239
240impl<ID> FiniteDigraph for VecGraph<ID>
241where
242    ID: PrimInt + Unsigned,
243{
244    fn src(&self, e: Self::Edge<'_>) -> Self::Node<'_> {
245        let eid = e.0.to_usize().unwrap();
246        Node(self.edges[eid >> 1].nodes[0])
247    }
248
249    fn snk(&self, e: Self::Edge<'_>) -> Self::Node<'_> {
250        let eid = e.0.to_usize().unwrap();
251        Node(self.edges[eid >> 1].nodes[1])
252    }
253}
254
255#[derive(Clone)]
256pub struct NeighIt<'a, ID>(SliceIter<'a, ID>);
257
258impl<'a, ID> GraphIterator<VecGraph<ID>> for NeighIt<'a, ID>
259where
260    ID: PrimInt + Unsigned,
261{
262    type Item = (Edge<ID>, Node<ID>);
263
264    fn next(&mut self, g: &VecGraph<ID>) -> Option<Self::Item> {
265        self.0.next().map(|&eid| {
266            let i = eid.to_usize().unwrap();
267            (Edge(eid), Node(g.edges[i >> 1].nodes[1 - (i & 1)]))
268        })
269    }
270}
271
272impl<ID> Undirected for VecGraph<ID>
273where
274    ID: PrimInt + Unsigned + 'static,
275{
276    type NeighIt<'a> = NeighIt<'a, ID>;
277
278    fn neigh_iter(&self, u: Self::Node<'_>) -> Self::NeighIt<'_> {
279        let uid = u.index();
280        let beg = self.nodes[uid].firstout.to_usize().unwrap();
281        let end = self
282            .nodes
283            .get(uid + 1)
284            .map(|n| n.firstout.to_usize().unwrap())
285            .unwrap_or_else(|| self.adj.len());
286        NeighIt(self.adj[beg..end].iter())
287    }
288}
289
290impl<ID> Directed for VecGraph<ID>
291where
292    ID: PrimInt + Unsigned + 'static,
293{
294    type OutIt<'a> = NeighIt<'a, ID>;
295
296    type InIt<'a> = NeighIt<'a, ID>;
297
298    type IncidentIt<'a> = NeighIt<'a, ID>;
299
300    type DirectedEdge<'a> = Self::Edge<'a>;
301
302    fn out_iter(&self, u: Self::Node<'_>) -> Self::OutIt<'_> {
303        let uid = u.index();
304        let beg = self.nodes[uid].firstout.to_usize().unwrap();
305        let end = self.nodes[uid].firstin.to_usize().unwrap();
306        NeighIt(self.adj[beg..end].iter())
307    }
308
309    fn in_iter(&self, u: Self::Node<'_>) -> Self::InIt<'_> {
310        let uid = u.index();
311        let beg = self.nodes[uid].firstin.to_usize().unwrap();
312        let end = self
313            .nodes
314            .get(uid + 1)
315            .map(|n| n.firstout.to_usize().unwrap())
316            .unwrap_or_else(|| self.adj.len());
317        NeighIt(self.adj[beg..end].iter())
318    }
319
320    fn incident_iter(&self, u: Self::Node<'_>) -> Self::IncidentIt<'_> {
321        self.neigh_iter(u)
322    }
323}
324
325impl<ID> IndexGraph for VecGraph<ID>
326where
327    ID: PrimInt + Unsigned + 'static,
328{
329    fn node_id(&self, u: Self::Node<'_>) -> usize {
330        u.index()
331    }
332
333    fn id2node(&self, id: usize) -> Self::Node<'_> {
334        debug_assert!(id < self.nodes.len(), "Invalid node id");
335        Node(ID::from(id).unwrap())
336    }
337
338    fn edge_id(&self, e: Self::Edge<'_>) -> usize {
339        e.index()
340    }
341
342    fn id2edge(&self, id: usize) -> Self::Edge<'_> {
343        debug_assert!(
344            id < self.edges.len(),
345            "Invalid edge id: {}({}), must be in 0..{}",
346            id,
347            id << 1,
348            self.edges.len()
349        );
350        Edge(ID::from(id << 1).unwrap())
351    }
352}
353
354/// A builder for a VecGraph.
355///
356/// The basic task is to arrange the final outgoing and incoming edges in the
357/// linked lists appropriately (i.e. first outgoing, then incoming edges).
358pub struct VecGraphBuilder<ID> {
359    /// The outgoing and incoming edges of each node.
360    nodes: Vec<[Vec<ID>; 2]>,
361
362    /// The end nodes of each edge.
363    edges: Vec<EdgeData<ID>>,
364}
365
366impl<ID> Builder for VecGraphBuilder<ID>
367where
368    ID: PrimInt + Unsigned,
369{
370    type Graph = VecGraph<ID>;
371    type Node = Node<ID>;
372    type Edge = Edge<ID>;
373
374    fn with_capacities(nnodes: usize, nedges: usize) -> Self {
375        VecGraphBuilder {
376            nodes: Vec::with_capacity(nnodes),
377            edges: Vec::with_capacity(nedges),
378        }
379    }
380
381    fn reserve(&mut self, nnodes: usize, nedges: usize) {
382        self.nodes.reserve(nnodes);
383        self.edges.reserve(nedges);
384    }
385
386    fn num_nodes(&self) -> usize {
387        self.nodes.len()
388    }
389
390    fn num_edges(&self) -> usize {
391        self.edges.len()
392    }
393
394    fn add_node(&mut self) -> Self::Node {
395        assert!(
396            self.nodes.len() + 1 < ID::max_value().to_usize().unwrap(),
397            "Node capacity exceeded"
398        );
399        let id = self.nodes.len();
400        self.nodes.push([vec![], vec![]]);
401        Node(ID::from(id).unwrap())
402    }
403
404    fn add_edge(&mut self, u: Self::Node, v: Self::Node) -> Self::Edge {
405        assert!(
406            self.edges.len() * 2 + 2 < ID::max_value().to_usize().unwrap(),
407            "Edge capacity exceeded"
408        );
409        let eid = ID::from(self.edges.len() << 1).unwrap();
410        self.edges.push(EdgeData { nodes: [u.0, v.0] });
411        self.nodes[u.index()][0].push(eid);
412        self.nodes[v.index()][1].push(eid | ID::one());
413        Edge(eid)
414    }
415
416    fn node2id(&self, u: Self::Node) -> usize {
417        u.index()
418    }
419
420    fn edge2id(&self, e: Self::Edge) -> usize {
421        e.index()
422    }
423
424    fn id2node(&self, uid: usize) -> Self::Node {
425        Node(ID::from(uid).unwrap())
426    }
427
428    fn id2edge(&self, eid: usize) -> Self::Edge {
429        Edge(ID::from(eid << 1).unwrap())
430    }
431
432    fn into_graph(self) -> VecGraph<ID> {
433        let mut nodes = Vec::with_capacity(self.nodes.len());
434        let mut adj = Vec::with_capacity(self.edges.len() * 2);
435
436        for [outs, ins] in self.nodes.into_iter() {
437            nodes.push(NodeData {
438                firstout: ID::from(adj.len()).unwrap(),
439                firstin: ID::from(adj.len() + outs.len()).unwrap(),
440            });
441            adj.extend(outs);
442            adj.extend(ins);
443        }
444
445        VecGraph {
446            nodes,
447            edges: self.edges,
448            adj,
449        }
450    }
451}
452
453impl<ID> Buildable for VecGraph<ID>
454where
455    ID: PrimInt + Unsigned,
456{
457    type Builder = VecGraphBuilder<ID>;
458}
459
460impl<ID> VecGraph<ID>
461where
462    ID: PrimInt + Unsigned,
463{
464    pub fn new() -> VecGraph<ID> {
465        VecGraph {
466            nodes: vec![],
467            edges: vec![],
468            adj: vec![],
469        }
470    }
471}
472
473impl<ID> Default for VecGraph<ID>
474where
475    ID: PrimInt + Unsigned,
476{
477    fn default() -> Self {
478        VecGraph::new()
479    }
480}
481
482#[cfg(test)]
483mod tests {
484    use crate::classes::*;
485    use crate::traits::Indexable;
486    use crate::traits::*;
487    use crate::VecGraph;
488    use std::cmp::{max, min};
489
490    #[test]
491    fn test_graph() {
492        const N: usize = 7;
493        let g = cycle::<VecGraph>(N);
494
495        assert_eq!(g.num_nodes(), N);
496        assert_eq!(g.num_edges(), N);
497
498        let mut balances = vec![0; g.num_nodes()];
499
500        for u in g.nodes() {
501            balances[g.node_id(u)] = u.index();
502        }
503
504        for u in g.nodes() {
505            assert_eq!(balances[g.node_id(u)], u.index());
506        }
507
508        for u in g.nodes() {
509            let mut neighs: Vec<_> = g.neighs(u).collect();
510
511            for &(e, v) in &neighs {
512                eprintln!(
513                    "{} {}->{} {}-{}",
514                    e.index(),
515                    u.index(),
516                    v.index(),
517                    g.enodes(e).0.index(),
518                    g.enodes(e).1.index()
519                );
520                assert!((g.enodes(e) == (u, v)) || (g.enodes(e) == (v, u)));
521            }
522
523            neighs.sort_by_key(|&(_, u)| u.index());
524
525            let x = (u.index() + N - 1) % N;
526            let y = (u.index() + 1) % N;
527            assert_eq!(
528                neighs.iter().map(|&(_, v)| v).collect::<Vec<_>>(),
529                vec![g.id2node(min(x, y)), g.id2node(max(x, y))]
530            );
531        }
532    }
533
534    #[test]
535    fn test_edge_vec() {
536        let g = cycle::<VecGraph>(7);
537
538        let mut x = vec![0; g.num_edges()];
539        for (i, e) in g.edges().enumerate() {
540            x[g.edge_id(e)] = i;
541        }
542
543        for u in g.nodes() {
544            for (e, _) in g.neighs(u) {
545                assert_eq!(x[g.edge_id(e)], e.index());
546            }
547        }
548    }
549
550    #[test]
551    fn test_digraph() {
552        for g in [cycle::<VecGraph>(7), peterson(), hypercube(5)].iter() {
553            for u in g.nodes() {
554                for (e, v) in g.outedges(u) {
555                    assert_eq!(u, g.src(e));
556                    assert_eq!(v, g.snk(e));
557                }
558                for (e, v) in g.inedges(u) {
559                    assert_eq!(v, g.src(e));
560                    assert_eq!(u, g.snk(e));
561                }
562                for (e, v) in g.incident_edges(u) {
563                    assert_eq!(
564                        v,
565                        if e.is_incoming() {
566                            g.src(e.edge())
567                        } else {
568                            g.snk(e.edge())
569                        }
570                    );
571                }
572            }
573        }
574    }
575
576    #[cfg(feature = "serialize")]
577    mod serialize {
578        use super::VecGraph;
579        use crate::classes::peterson;
580        use crate::traits::{FiniteDigraph, FiniteGraph, IndexGraph};
581        use serde_json;
582
583        #[test]
584        fn test_serde() {
585            let g = peterson::<VecGraph>();
586
587            let serialized = serde_json::to_string(&g).unwrap();
588
589            println!("serialized = {}", serialized);
590
591            let h: VecGraph = serde_json::from_str(&serialized).unwrap();
592
593            assert_eq!(g.num_nodes(), h.num_nodes());
594            assert_eq!(g.num_edges(), h.num_edges());
595            for e in g.edges() {
596                let f = h.id2edge(g.edge_id(e));
597                assert_eq!(g.node_id(g.src(e)), h.node_id(h.src(f)));
598                assert_eq!(g.node_id(g.snk(e)), h.node_id(h.snk(f)));
599            }
600        }
601
602        #[test]
603        fn test_serialize() {
604            use crate::{Buildable, Builder};
605            let g = VecGraph::<u32>::new_with(|b| {
606                let nodes = b.add_nodes(5);
607                b.add_edge(nodes[0], nodes[1]);
608                b.add_edge(nodes[0], nodes[2]);
609                b.add_edge(nodes[1], nodes[4]);
610                b.add_edge(nodes[2], nodes[3]);
611            });
612
613            let serialized = serde_json::to_string(&g).unwrap();
614            let g2: VecGraph<u32> = serde_json::from_str(&serialized).unwrap();
615
616            assert_eq!(g.num_nodes(), g2.num_nodes());
617            let mut edges = g2
618                .edges()
619                .map(|e| {
620                    let (u, v) = g2.enodes(e);
621                    let (u, v) = (g2.node_id(u), g2.node_id(v));
622                    (u.min(v), u.max(v))
623                })
624                .collect::<Vec<_>>();
625            edges.sort();
626            assert_eq!(edges, vec![(0, 1), (0, 2), (1, 4), (2, 3)]);
627        }
628    }
629}