snark_tool/service/matching/
perfect_matchings.rs1use crate::graph::edge::{Edge, EdgeConstructor};
2use crate::graph::graph::Graph;
3use crate::graph::undirected::edge::UndirectedEdge;
4use std::collections::VecDeque;
5use std::slice;
6
7#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd)]
10pub struct Matching {
11 pub edges: Vec<UndirectedEdge>,
12}
13
14impl Matching {
15 pub fn new() -> Self {
16 Matching { edges: vec![] }
17 }
18}
19
20#[derive(Debug, Clone)]
21pub struct MatchingGraph {
22 vertices: Vec<MatchingVertex>,
23 size: usize,
24}
25
26#[derive(Debug, Clone)]
27pub struct MatchingVertex {
28 index: usize,
29 active: bool,
30 neighbors: Vec<usize>,
31}
32
33impl MatchingVertex {
34 pub fn new(index: usize) -> Self {
35 MatchingVertex {
36 index,
37 active: true,
38 neighbors: vec![],
39 }
40 }
41
42 pub fn new_non_active(index: usize) -> Self {
43 MatchingVertex {
44 index,
45 active: false,
46 neighbors: vec![],
47 }
48 }
49
50 pub fn index(&self) -> &usize {
51 &self.index
52 }
53
54 #[allow(dead_code)]
55 pub fn neighbors(&self) -> &Vec<usize> {
56 &self.neighbors
57 }
58}
59
60#[allow(dead_code)]
61impl MatchingGraph {
62 pub fn new() -> Self {
63 Self::with_capacity(0)
64 }
65
66 pub fn with_capacity(capacity: usize) -> Self {
67 MatchingGraph {
68 vertices: Vec::with_capacity(capacity),
69 size: 0,
70 }
71 }
72
73 pub fn from_graph<G: Graph>(graph: &G) -> Self {
74 let mut match_graph = MatchingGraph::with_capacity(graph.size());
75 for edge in graph.edges() {
76 match_graph.add_edge(edge.from(), edge.to());
77 }
78 match_graph
79 }
80
81 pub fn has_edge(&self, from: usize, to: usize) -> bool {
82 if !self.vertices[from].active || !self.vertices[to].active {
83 return false;
84 }
85 let mut first = false;
86 for neighbor in self.neighbors(from) {
87 if neighbor == &to {
88 first = true;
89 break;
90 }
91 }
92 if !first {
93 return false;
94 }
95 let mut second = false;
96 for neighbor in self.neighbors(to) {
97 if neighbor == &from {
98 second = true;
99 }
100 }
101 if !second {
102 return false;
103 }
104 true
105 }
106
107 pub fn add_edge(&mut self, from: usize, to: usize) {
108 self.create_vertex_if_not_exists(from);
109 self.create_vertex_if_not_exists(to);
110 self.vertices[from]
111 .neighbors
112 .retain(|neighbor| neighbor != &to);
113 self.vertices[from].neighbors.push(to);
114 self.vertices[to]
115 .neighbors
116 .retain(|neighbor| neighbor != &from);
117 self.vertices[to].neighbors.push(from);
118 }
119
120 pub fn remove_edge(&mut self, from: usize, to: usize) {
121 self.vertices[from]
122 .neighbors
123 .retain(|neighbor| neighbor != &to);
124 self.vertices[to]
125 .neighbors
126 .retain(|neighbor| neighbor != &from);
127 }
128
129 pub fn create_vertex_if_not_exists(&mut self, vertex: usize) {
133 if self.vertices.len() > vertex {
134 if !self.vertices[vertex].active {
135 self.size += 1;
136 self.vertices[vertex].active = true;
137 self.vertices[vertex].neighbors = vec![];
138 }
139 return;
140 }
141 while self.vertices.len() <= vertex {
142 if self.vertices.len() == vertex {
143 self.vertices.push(MatchingVertex::new(self.vertices.len()));
144 self.size += 1;
145 } else {
146 self.vertices
147 .push(MatchingVertex::new_non_active(self.vertices.len()));
148 }
149 }
150 }
151
152 pub fn add_vertex(&mut self, vertex: MatchingVertex) {
153 self.create_vertex_if_not_exists(vertex.index);
154 for neighbor in vertex.neighbors.iter() {
155 self.create_vertex_if_not_exists(*neighbor);
156 let mut already_has = false;
157 for neighbor in self.vertices[*neighbor].neighbors.iter() {
158 if neighbor == &vertex.index {
159 already_has = true;
160 break;
161 }
162 }
163 if !already_has {
164 self.vertices[*neighbor].neighbors.push(vertex.index);
165 }
166 }
167 self.vertices[vertex.index].neighbors = vertex.neighbors;
168 }
169
170 pub fn size(&self) -> usize {
171 self.size
172 }
173
174 pub fn max_vertex_index(&self) -> usize {
175 self.vertices.len()
176 }
177
178 pub fn vertices(&self) -> MatchingGraphVerticesIter {
179 MatchingGraphVerticesIter {
180 vertices: self.vertices.iter(),
181 }
182 }
183
184 pub fn neighbors(&self, vertex: usize) -> &Vec<usize> {
188 &self.vertices[vertex].neighbors
189 }
190
191 fn first_vertex(&self) -> Option<&MatchingVertex> {
192 for vertex in self.vertices.iter() {
193 if vertex.active {
194 return Some(vertex);
195 }
196 }
197 None
198 }
199
200 pub fn remove_vertex(&mut self, vertex: usize) {
201 let neighbors = self.vertices[vertex].neighbors.clone();
202 for neighbor in neighbors {
203 self.vertices[neighbor]
204 .neighbors
205 .retain(|neighb| neighb != &vertex);
206 }
207 self.vertices[vertex].active = false;
208 self.size -= 1;
209 }
210
211 pub fn has_odd_size_component(&mut self) -> bool {
212 let mut removed_vertices = vec![];
213 while let Some(start) = self.first_vertex() {
214 let mut bfs_graph = BfsGraph::new(self, start.index);
215 let mut visited_vertices = vec![];
216 while let Some(vertex) = bfs_graph.bfs_next() {
217 visited_vertices.push(vertex);
218 }
219 if visited_vertices.len() % 2 == 1 {
220 self.activate_vertices(removed_vertices);
221 return true;
222 }
223
224 if visited_vertices.len() == self.size() {
226 return false;
227 }
228 for visited_vertex in visited_vertices {
230 removed_vertices.push(visited_vertex);
231 self.vertices[visited_vertex].active = false;
232 }
233 }
234 self.activate_vertices(removed_vertices);
235 false
236 }
237
238 fn activate_vertices(&mut self, vertices_to_activate: Vec<usize>) {
239 for vertex_to_activate in vertices_to_activate {
240 self.vertices[vertex_to_activate].active = true;
241 }
242 }
243
244 pub fn perfect_matchings(&mut self) -> Vec<Matching> {
245 let mut matchings = vec![];
246 if self.size == 0 {
247 matchings.push(Matching::new());
248 return matchings;
249 }
250 if !self.has_odd_size_component() {
251 if let Some(vertex) = self.first_vertex() {
252 let vertex = vertex.clone();
253 for neighbor in vertex.neighbors.iter() {
254 let mut removed_vertices = vec![];
256 removed_vertices.push(self.vertices[vertex.index].clone());
257 removed_vertices.push(self.vertices[*neighbor].clone());
258
259 self.remove_vertex(vertex.index);
260 self.remove_vertex(*neighbor);
261 let mut matchings_local = self.perfect_matchings();
262 for matching in matchings_local.iter_mut() {
263 matching
264 .edges
265 .push(UndirectedEdge::new(vertex.index, *neighbor));
266 }
267 matchings.append(&mut matchings_local);
268 for removed_vertex in removed_vertices {
270 self.add_vertex(removed_vertex);
271 }
272 }
273 }
274 }
275 matchings
276 }
277}
278
279pub struct MatchingGraphVerticesIter<'a> {
280 vertices: slice::Iter<'a, MatchingVertex>,
281}
282
283impl<'a> Iterator for MatchingGraphVerticesIter<'a> {
284 type Item = &'a MatchingVertex;
285
286 fn next(&mut self) -> Option<Self::Item> {
287 while let Some(vertex) = self.vertices.next() {
288 if vertex.active {
289 return Some(vertex);
290 }
291 }
292 None
293 }
294}
295
296pub struct BfsGraph<'a> {
297 graph: &'a MatchingGraph,
298 visited: Vec<bool>,
299 to_visit: VecDeque<usize>,
300}
301
302impl<'a> BfsGraph<'a> {
303 pub fn new(graph: &'a MatchingGraph, start: usize) -> Self {
304 let visited = vec![false; graph.vertices.len()];
305 let mut to_visit = VecDeque::new();
306 to_visit.push_back(start);
307
308 let mut bfs = Self {
309 graph,
310 visited,
311 to_visit,
312 };
313 bfs.visit(start);
314 bfs
315 }
316
317 fn visit(&mut self, vertex: usize) -> bool {
321 let old_val = self.visited[vertex];
322 self.visited[vertex] = true;
323 !old_val
324 }
325
326 pub fn bfs_next(&mut self) -> Option<usize> {
327 if let Some(vertex) = self.to_visit.pop_front() {
328 for neighbor in self.graph.neighbors(vertex) {
329 if self.visit(*neighbor) {
330 self.to_visit.push_back(*neighbor);
331 }
332 }
333 return Some(vertex);
334 }
335 None
336 }
337}