snark_tool/graph/undirected/multi_graph/
graph.rs

1use crate::graph::edge::{Edge, EdgeConstructor};
2use crate::graph::graph::{Graph, GraphConstructor};
3use crate::graph::undirected::edge::UndirectedEdge;
4use crate::graph::undirected::vertex::VertexWithEdges;
5use crate::graph::undirected::UndirectedGraph;
6use crate::graph::vertex::{Vertex, VertexConstructor};
7use std::{fmt, slice};
8
9///
10/// Can hold multiple edges from one vertex to another
11///
12#[derive(Debug, Clone)]
13pub struct MultiGraph {
14    pub vertices: Vec<VertexWithEdges>,
15}
16
17impl UndirectedGraph for MultiGraph {}
18
19impl Graph for MultiGraph {
20    type V = VertexWithEdges;
21    type E = UndirectedEdge;
22
23    fn size(&self) -> usize {
24        self.vertices.len()
25    }
26
27    fn has_edge(&self, from: usize, to: usize) -> bool {
28        if from >= self.vertices.len() || to >= self.vertices.len() {
29            return false;
30        }
31        let from_vertex = &self.vertices[from];
32        for edge in from_vertex.edges.iter() {
33            if edge.from() == from && edge.to() == to || edge.from() == to && edge.to() == from {
34                return true;
35            }
36        }
37        false
38    }
39
40    fn add_vertex(&mut self) {
41        self.vertices
42            .push(VertexWithEdges::new(self.vertices.len()));
43    }
44
45    fn add_edge(&mut self, from: usize, to: usize) {
46        let edge = UndirectedEdge::new(from, to);
47        if from == to {
48            return;
49        }
50        while self.vertices.len() <= edge.to() {
51            self.add_non_active_vertex();
52        }
53        let from_vertex = &mut self.vertices[from];
54        from_vertex.add_edge(to, 0);
55        from_vertex.set_active(true);
56        let to_vertex = &mut self.vertices[to];
57        to_vertex.add_edge(from, 0);
58        to_vertex.set_active(true);
59    }
60
61    fn remove_edge(&mut self, from: usize, to: usize) {
62        let edge_to_remove = UndirectedEdge::new(from, to);
63
64        let from_vertex = &mut self.vertices[from];
65
66        let pos = from_vertex.edges.iter().position(|x| *x == edge_to_remove);
67        if let Some(position) = pos {
68            from_vertex.edges.remove(position);
69        }
70
71        let to_vertex = &mut self.vertices[to];
72        let pos = to_vertex.edges.iter().position(|x| *x == edge_to_remove);
73        if let Some(position) = pos {
74            to_vertex.edges.remove(position);
75        }
76    }
77
78    fn remove_edges_of_vertex(&mut self, vertex: usize) {
79        if vertex >= self.vertices.len() {
80            return;
81        }
82        let neighbors = self.vertices[vertex].neighbors().clone();
83        self.vertices[vertex].edges = vec![];
84        for neighbor in neighbors {
85            let edge_to_remove = UndirectedEdge::new(vertex, neighbor);
86            self.vertices[neighbor].edges.retain(|edge| {
87                edge_to_remove.from() != edge.from() || edge_to_remove.to() != edge.to()
88            });
89        }
90    }
91
92    fn remove_vertex(&mut self, vertex_index: usize) {
93        self.remove_edges_of_vertex(vertex_index)
94    }
95
96    fn vertices<'a>(&'a self) -> Box<dyn Iterator<Item = &'a VertexWithEdges> + 'a> {
97        Box::new(Vertices::new(self.vertices.iter()))
98    }
99
100    fn edges<'a>(&'a self) -> Box<dyn Iterator<Item = &'a UndirectedEdge> + 'a> {
101        Box::new(Edges::new(&self.vertices))
102    }
103
104    fn edges_of_vertex<'a>(
105        &'a self,
106        vertex: usize,
107    ) -> Box<dyn Iterator<Item = &'a UndirectedEdge> + 'a> {
108        Box::new(self.vertices[vertex].edges.iter())
109    }
110
111    fn neighbors_of_vertex(&self, vertex: usize) -> Vec<usize> {
112        let mut neighbors = vec![];
113        let mut edges = self.edges_of_vertex(vertex);
114        while let Some(edge) = edges.next() {
115            if edge.from() == vertex {
116                neighbors.push(edge.to());
117            } else {
118                neighbors.push(edge.from());
119            }
120        }
121        neighbors.sort();
122        neighbors.dedup();
123        neighbors
124    }
125}
126
127impl GraphConstructor for MultiGraph {
128    fn new() -> Self {
129        Self::with_vertices_capacity(20)
130    }
131
132    fn with_capacity(vertices: usize, _edges: usize) -> Self {
133        Self::with_vertices_capacity(vertices)
134    }
135
136    fn with_vertices_capacity(vertices: usize) -> Self {
137        MultiGraph {
138            vertices: Vec::with_capacity(vertices),
139        }
140    }
141}
142
143impl MultiGraph {
144    pub fn from_graph<G: Graph>(graph: &G) -> Self {
145        let mut result = MultiGraph::with_vertices_capacity(graph.size());
146        for edge in graph.edges() {
147            result.add_edge(edge.from(), edge.to());
148        }
149        result
150    }
151
152    ///
153    /// for now has_vertex for vertex v is true if graph contains edge connected to vertex v
154    ///
155    pub fn has_vertex(&self, vertex: usize) -> bool {
156        if vertex >= self.size() {
157            return false;
158        }
159        self.vertices[vertex].active()
160    }
161
162    #[allow(dead_code)]
163    pub fn first_vertex(&self) -> Option<&VertexWithEdges> {
164        for vertex in self.vertices() {
165            if self.has_vertex(vertex.index()) {
166                return Some(vertex);
167            }
168        }
169        None
170    }
171
172    #[allow(dead_code)]
173    pub fn vertex(&self, index: usize) -> Option<&VertexWithEdges> {
174        if !self.has_vertex(index) {
175            return None;
176        }
177        Some(&self.vertices[index])
178    }
179
180    pub fn remove_vertex(&mut self, vertex: usize) {
181        if vertex >= self.vertices.len() {
182            return;
183        }
184        self.remove_edges_of_vertex(vertex);
185        self.vertices[vertex].set_active(false);
186    }
187
188    fn add_non_active_vertex(&mut self) {
189        self.vertices
190            .push(VertexWithEdges::new_non_active(self.vertices.len()));
191    }
192}
193
194/// Vertices
195pub struct Vertices<'a> {
196    vertices: slice::Iter<'a, VertexWithEdges>,
197}
198
199impl<'a> Vertices<'a> {
200    pub fn new(vertices: slice::Iter<'a, VertexWithEdges>) -> Self {
201        Vertices { vertices }
202    }
203}
204
205impl<'a> Iterator for Vertices<'a> {
206    type Item = &'a VertexWithEdges;
207
208    fn next(&mut self) -> Option<Self::Item> {
209        if let Some(vertex) = self.vertices.next() {
210            if vertex.active() {
211                return Some(vertex);
212            }
213            return self.next();
214        }
215        None
216    }
217}
218
219/// Edges
220pub struct Edges<'a> {
221    vertices: &'a Vec<VertexWithEdges>,
222    position: (usize, usize),
223}
224
225impl<'a> Edges<'a> {
226    pub fn new(vertices: &'a Vec<VertexWithEdges>) -> Self {
227        Edges {
228            vertices,
229            position: (0, 0),
230        }
231    }
232}
233
234impl<'a> Iterator for Edges<'a> {
235    type Item = &'a UndirectedEdge;
236    fn next(&mut self) -> Option<Self::Item> {
237        if self.vertices.len() <= self.position.0 {
238            return None;
239        }
240
241        let vertex = &self.vertices[self.position.0];
242        if vertex.edges.len() <= self.position.1 {
243            self.position.0 += 1;
244            self.position.1 = 0;
245            return self.next();
246        }
247
248        let neighboring_edge = &vertex.edges[self.position.1];
249
250        if neighboring_edge.from() != vertex.index() {
251            self.position.1 += 1;
252            return self.next();
253        }
254
255        self.position.1 += 1;
256        Some(neighboring_edge)
257    }
258}
259
260impl fmt::Display for MultiGraph {
261    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
262        for vertex in &self.vertices {
263            write!(f, "{}: ", vertex.index())?;
264            let mut separ = String::from("");
265            for edge in vertex.edges.iter() {
266                let neighbor = if edge.from() == vertex.index() {
267                    edge.to()
268                } else {
269                    edge.from()
270                };
271                write!(f, "{}{}", separ, neighbor)?;
272                separ = String::from(", ");
273            }
274
275            writeln!(f)?;
276        }
277        Ok(())
278    }
279}