1#[cfg(test)]
2mod unit_test;
3use crate::graph::{VertexInfo, Weight};
4use crate::utils::read_lines;
5use std::collections::HashSet;
6use std::path::Path;
7
8#[derive(Eq, Hash, PartialEq, Copy, Clone)]
9pub struct DirectedEdge {
10 from: usize, to: usize,
12}
13
14impl DirectedEdge {
15 pub fn init(origin: usize, destination: usize) -> Self {
16 Self {
17 from: origin,
18 to: destination,
19 }
20 }
21 pub fn to(&self) -> &usize {
22 &self.to
23 }
24 pub fn from(&self) -> &usize {
25 &self.from
26 }
27}
28pub struct DirectedGraph {
40 data: Vec<HashSet<DirectedEdge>>,
44 nb_edges: usize,
45 nb_vertices: usize,
46 in_edges: Vec<HashSet<usize>>,
47}
48impl Default for DirectedGraph {
49 fn default() -> Self {
50 Self::new()
51 }
52}
53impl DirectedGraph {
54 pub fn new() -> Self {
56 Self {
57 data: Vec::new(),
58 nb_edges: 0,
59 nb_vertices: 0,
60 in_edges: Vec::new(),
61 }
62 }
63 pub fn init(nb_objects: usize) -> Self {
65 let mut graph = Self::new();
66 graph.nb_vertices = nb_objects;
67 graph.data = Vec::with_capacity(nb_objects);
68 for _ in 0..nb_objects {
69 graph.data.push(HashSet::new());
70 graph.in_edges.push(HashSet::new());
71 }
72 graph
73 }
74 pub fn reverse(&self) -> Self {
76 let nb_vertices = self.nb_vertices;
78 let mut rev_graph = Self::init(nb_vertices);
79 for v in 0..nb_vertices {
80 let adj_v = self.vertex_edges(&v);
81 for w in adj_v {
82 rev_graph.add_edge(*w, v);
83 }
84 }
85 rev_graph
86 }
87 pub fn from_file<P>(filename: P, sep: char, nb_vertices: usize) -> Self
89 where
90 P: AsRef<Path>,
91 {
92 let mut nb_iter = 0;
98 println!("Initializing the graph");
99 let mut dg = DirectedGraph::init(nb_vertices);
100 match read_lines(filename) {
101 Ok(lines) => {
102 for (_, line) in lines.enumerate() {
103 if let Ok(row) = line {
104 let values = row.split(sep).collect::<Vec<&str>>();
105 for i in 1..values.len() {
106 dg.add_edge(
107 values[0].parse::<usize>().unwrap(),
108 values[i].parse::<usize>().unwrap(),
109 );
110 }
111 println!("{nb_iter}");
113 nb_iter += 1
114 }
115 }
116 }
117 Err(error) => panic!("{error}"),
118 }
119 dg
120 }
121
122 pub fn nb_edges(&self) -> usize {
124 self.nb_edges
126 }
127 pub fn nb_vertices(&self) -> usize {
129 self.nb_vertices
131 }
132 pub fn add_edge(&mut self, v: usize, w: usize) {
134 assert!(self.nb_vertices >= std::cmp::max(v, w));
137 let edge = DirectedEdge::init(v, w);
138 let w_is_in = self.data[v].insert(edge);
139 self.in_edges[w].insert(v);
140 if w_is_in {
141 self.nb_edges += 1;
143 }
144 }
145 pub fn add_vertex(&mut self) {
147 self.data.push(HashSet::<DirectedEdge>::new());
148 self.nb_vertices += 1;
149 }
150 pub fn vertex_edges(&self, v: &usize) -> Vec<&usize> {
152 self.data[*v]
156 .iter()
157 .map(|edge| edge.to())
158 .collect::<Vec<&usize>>()
159 }
160 pub fn out_edges(&self, v: &usize) -> &HashSet<DirectedEdge> {
162 &self.data[*v]
166 }
167 pub fn in_edges(&self, v: &usize) -> &HashSet<usize> {
169 &self.in_edges[*v]
175 }
176 pub fn out_degree(&self, v: &usize) -> usize {
178 self.vertex_edges(v).len()
180 }
181 pub fn in_degree(&self, v: &usize) -> usize {
183 self.data
185 .iter()
186 .map(|adj| usize::from(adj.iter().any(|e| e.to() == v)))
187 .sum()
188 }
189 pub fn average_degree(&self) -> usize {
191 if self.nb_vertices > 0 {
193 self.nb_edges / self.nb_vertices
194 } else {
195 panic!("No vertex in the graph");
196 }
197 }
198 pub fn self_loop_number(&self) -> usize {
200 self.data
201 .iter()
202 .enumerate()
203 .map(|(v, e)| usize::from(e.contains(&DirectedEdge::init(v, v))))
204 .sum()
205 }
206}
207impl VertexInfo for DirectedGraph {
208 fn vertex_edges(&self, v: &usize) -> Vec<&usize> {
209 self.vertex_edges(v)
213 }
214 fn nb_vertices(&self) -> usize {
215 self.nb_vertices
217 }
218}
219
220#[derive(Eq, Hash, PartialEq, Copy, Clone, Debug)]
221struct DirectedWeightedEdge<T>
222where
223 T: Weight,
224{
225 from: usize, to: usize,
227 weight: T,
228}
229impl<T: Weight> DirectedWeightedEdge<T> {
230 pub fn init(origin: usize, destination: usize, cost: T) -> Self {
231 Self {
232 from: origin,
233 to: destination,
234 weight: cost,
235 }
236 }
237 pub fn to(&self) -> &usize {
238 &self.to
239 }
240 pub fn from(&self) -> &usize {
241 &self.from
242 }
243 pub fn weight(&self) -> &T {
244 &self.weight
245 }
246}
247
248pub struct EdgeWeightedDigraph<T>
249where
250 T: Weight,
251{
252 data: Vec<HashSet<DirectedWeightedEdge<T>>>,
253 nb_edges: usize,
254 nb_vertices: usize,
255}
256
257impl<T: Weight> Default for EdgeWeightedDigraph<T> {
258 fn default() -> Self {
259 Self::new()
260 }
261}
262impl<T: Weight> EdgeWeightedDigraph<T> {
263 pub fn new() -> Self {
265 Self {
266 data: Vec::new(),
267 nb_edges: 0,
268 nb_vertices: 0,
269 }
270 }
271 pub fn init(nb_objects: usize) -> Self {
273 let mut graph = Self::new();
274 graph.nb_vertices = nb_objects;
275 graph.data = Vec::with_capacity(nb_objects);
276 for _ in 0..nb_objects {
277 graph.data.push(HashSet::new());
278 }
279 graph
280 }
281 pub fn nb_edges(&self) -> usize {
283 self.nb_edges
285 }
286 pub fn nb_vertices(&self) -> usize {
288 self.nb_vertices
290 }
291 pub fn add_edge(&mut self, u: usize, v: usize, w: T) {
293 assert!(self.nb_vertices >= std::cmp::max(u, v));
296 let edge = DirectedWeightedEdge::init(u, v, w);
297 let is_new = self.data[u].insert(edge);
299 if is_new {
300 self.nb_edges += 1;
302 }
303 }
304 pub fn add_vertex(&mut self) {
306 self.data.push(HashSet::new());
307 self.nb_vertices += 1;
308 }
309 pub fn vertex_edges(&self, v: &usize) -> Vec<(&usize, &T)> {
311 self.data[*v]
315 .iter()
316 .map(|edge| (edge.to(), edge.weight()))
317 .collect::<Vec<(&usize, &T)>>()
318 }
319 pub fn out_degree(&self, v: &usize) -> usize {
321 self.vertex_edges(v).len()
323 }
324 pub fn in_degree(&self, v: &usize) -> usize {
326 self.data
328 .iter()
329 .map(|adj| usize::from(adj.iter().any(|edge| v == edge.to())))
330 .sum()
331 }
332 pub fn average_degree(&self) -> usize {
334 if self.nb_vertices > 0 {
336 self.nb_edges / self.nb_vertices
337 } else {
338 panic!("No vertex in the graph");
339 }
340 }
341 pub fn self_loop_number(&self) -> usize {
343 self.data
344 .iter()
345 .map(|adj| usize::from(adj.iter().any(|edge| edge.from() == edge.to())))
346 .sum()
347 }
348}
349impl<T: Weight> VertexInfo for EdgeWeightedDigraph<T> {
350 fn vertex_edges(&self, v: &usize) -> Vec<&usize> {
351 self.data[*v]
354 .iter()
355 .map(|edge| edge.to())
356 .collect::<Vec<&usize>>()
357 }
358 fn nb_vertices(&self) -> usize {
359 self.nb_vertices
361 }
362}
363
364#[derive(Debug, Eq, Hash, PartialEq, Copy, Clone)]
365pub struct FlowEdge<T>
366where
367 T: Weight,
368{
369 from: usize,
370 to: usize,
371 flow: T,
372 capacity: T,
373}
374
375impl<T: Weight> FlowEdge<T> {
376 pub fn init(origin: usize, destination: usize, f: T, c: T) -> Self {
377 Self {
378 from: origin,
379 to: destination,
380 flow: f,
381 capacity: c,
382 }
383 }
384
385 pub fn from(&self) -> &usize {
386 &self.from
387 }
388
389 pub fn to(&self) -> &usize {
390 &self.to
391 }
392
393 pub fn flow(&self) -> &T {
394 &self.flow
395 }
396 pub fn flow_mut(&mut self) -> &mut T {
397 &mut self.flow
398 }
399
400 pub fn capacity(&self) -> &T {
401 &self.capacity
402 }
403}
404
405impl<T: Weight> FlowEdge<T> {
406 pub fn residual_capacity(&self) -> T {
407 self.capacity - self.flow
408 }
409 pub fn add_residual_flow_to(&mut self, vertex: &usize, delta: T) {
410 if vertex == self.from() {
411 self.flow = self.flow - delta;
412 } else if vertex == self.to() {
413 self.flow = self.flow + delta;
414 } else {
415 panic!("Illegal endpoint {vertex}")
416 }
417 }
418}
419
420pub struct FlowNetwork<T>
421where
422 T: Weight,
423{
424 data: Vec<Vec<FlowEdge<T>>>,
425 nb_edges: usize,
426 nb_vertices: usize,
427}
428
429impl<T: Weight> FlowNetwork<T> {
430 pub fn new() -> Self {
432 Self {
433 data: Vec::new(),
434 nb_edges: 0,
435 nb_vertices: 0,
436 }
437 }
438 pub fn init(nb_objects: usize) -> Self {
440 let mut graph = Self::new();
441 graph.nb_vertices = nb_objects;
442 graph.data = Vec::with_capacity(nb_objects);
443 for _ in 0..nb_objects {
444 graph.data.push(Vec::new());
445 }
446 graph
447 }
448 pub fn nb_edges(&self) -> usize {
450 self.nb_edges
452 }
453 pub fn nb_vertices(&self) -> usize {
455 self.nb_vertices
457 }
458 pub fn add_edge(&mut self, from: usize, to: usize, cap: T) {
460 assert!(self.nb_vertices >= std::cmp::max(from, to));
463 let zero = Weight::zero();
464 let forward_edge = FlowEdge::init(from, to, zero, cap);
465 let backward_edge = FlowEdge::init(to, from, zero, zero);
466 if !self.data[from].contains(&forward_edge) {
467 self.data[from].push(forward_edge);
468 self.data[to].push(backward_edge);
469 self.nb_edges += 1;
470 }
471 }
472 pub fn add_vertex(&mut self) {
474 self.data.push(Vec::new());
475 self.nb_vertices += 1;
476 }
477 pub fn vertex_edges(&self, v: &usize) -> Vec<&FlowEdge<T>> {
479 self.data[*v].iter().collect::<Vec<&FlowEdge<T>>>()
483 }
484 pub fn vertex_edges_mut(&mut self, v: &usize) -> std::slice::IterMut<'_, FlowEdge<T>> {
485 self.data[*v].iter_mut()
489 }
490 pub fn out_degree(&self, v: &usize) -> usize {
492 self.vertex_edges(v).len()
494 }
495 pub fn in_degree(&self, v: &usize) -> usize {
497 self.data
499 .iter()
500 .map(|adj| usize::from(adj.iter().any(|edge| v == edge.to())))
501 .sum()
502 }
503 pub fn average_degree(&self) -> usize {
505 if self.nb_vertices > 0 {
507 self.nb_edges / self.nb_vertices
508 } else {
509 panic!("No vertex in the graph");
510 }
511 }
512 pub fn self_loop_number(&self) -> usize {
514 self.data
515 .iter()
516 .map(|adj| usize::from(adj.iter().any(|edge| edge.from() == edge.to())))
517 .sum()
518 }
519}