1use std::collections::HashMap;
2use std::collections::HashSet;
3use std::collections::VecDeque;
4use std::fmt::Debug;
5use std::hash::Hash;
6
7use self::traits::ArithmeticallyWeightedGraph;
8use self::traits::GraphBuilding;
9use self::traits::NodeNotFound;
10use self::traits::Traversable;
11
12pub mod traits;
13
14#[derive(Debug, Clone)]
18pub struct UnGraph<T, W> {
19 nodes: HashSet<T>,
20 edges: HashMap<T, HashMap<T, W>>,
21
22 empty: HashMap<T, W>,
23}
24
25impl<T, W> UnGraph<T, W>
26where
27 T: Clone + Copy + Hash + Eq + PartialEq,
28 W: Clone + Copy,
29{
30 pub fn new() -> Self {
32 Self::default()
33 }
34
35 pub fn basic_cycles(&self) -> Vec<Vec<T>> {
62 let mut remaining_edges = self.all_edges();
63
64 let mut spanning_forest = UnGraph::default();
65 let mut visited = HashSet::new();
66
67 for node in self.nodes() {
68 if visited.contains(&node) {
69 continue;
70 }
71
72 let mut queue = VecDeque::new();
73 queue.push_back((node, node));
74
75 while let Some((previous_node, inner_node)) = queue.pop_front() {
76 if visited.contains(&inner_node) {
77 continue;
78 }
79
80 remaining_edges.remove(&(inner_node, previous_node));
81 remaining_edges.remove(&(previous_node, inner_node));
82 spanning_forest.add_edge(previous_node, inner_node, 1);
83
84 visited.insert(inner_node);
85
86 for (target, _) in self.edges(&inner_node) {
87 if visited.contains(&target) {
88 continue;
89 }
90
91 queue.push_back((inner_node, target));
92 }
93 }
94 }
95
96 let mut cycles = Vec::new();
97
98 for edge in remaining_edges {
99 if let Some(path) = spanning_forest.find_path(edge.0, edge.1) {
100 cycles.push(path);
101 }
102 }
103
104 cycles
105 }
106
107 pub fn all_edges(&self) -> HashSet<(T, T)> {
125 let mut edges = HashSet::new();
126
127 for (origin, destinations) in &self.edges {
128 for dest in destinations.keys() {
129 if edges.contains(&(*dest, *origin)) {
130 continue;
131 }
132 edges.insert((*origin, *dest));
133 }
134 }
135
136 edges
137 }
138}
139
140impl<T, W> GraphBuilding<T, W> for UnGraph<T, W>
141where
142 T: Clone + Copy + Hash + Eq + PartialEq,
143 W: Clone + Copy,
144{
145 fn add_edge(&mut self, from: T, to: T, weight: W) {
146 self.edges.entry(from).or_default().insert(to, weight);
147 self.edges.entry(to).or_default().insert(from, weight);
148
149 self.nodes.insert(from);
150 self.nodes.insert(to);
151 }
152
153 fn add_node(&mut self, node: T) -> bool {
154 self.nodes.insert(node)
155 }
156
157 fn remove_edge(&mut self, from: T, to: T) -> Result<(), NodeNotFound> {
158 self.edges.get_mut(&from).ok_or(NodeNotFound)?.remove(&to);
159 self.edges.get_mut(&to).ok_or(NodeNotFound)?.remove(&from);
160
161 Ok(())
162 }
163
164 fn remove_node(&mut self, node: T) -> Result<(), NodeNotFound> {
165 if !self.nodes.remove(&node) {
166 return Err(NodeNotFound);
167 }
168
169 self.edges.remove_entry(&node);
170
171 for edges in self.edges.values_mut() {
172 edges.remove(&node);
173 }
174
175 Ok(())
176 }
177
178 fn has_edge(&self, from: T, to: T) -> bool {
179 self.edges
180 .get(&from)
181 .map_or(false, |edges| edges.contains_key(&to))
182 }
183}
184
185impl<T, W> Traversable<T, W> for UnGraph<T, W>
186where
187 T: Clone + Copy + Hash + Eq + PartialEq,
188 W: Clone + Copy,
189{
190 fn nodes(&self) -> traits::NodeIter<'_, T> {
191 traits::NodeIter {
192 nodes_iter: self.nodes.iter(),
193 }
194 }
195
196 fn edge_weight(&self, from: T, to: T) -> Result<W, NodeNotFound> {
197 self.edges
198 .get(&from)
199 .ok_or(NodeNotFound)?
200 .get(&to)
201 .ok_or(NodeNotFound)
202 .copied()
203 }
204
205 fn edges(&self, n: &T) -> traits::EdgeIterType<T, W> {
206 let edges = self.edges.get(n);
207
208 if let Some(edges) = edges {
209 traits::EdgeIterType::EdgeIter(traits::EdgeIter {
210 edge_iter: edges.iter(),
211 })
212 } else {
213 traits::EdgeIterType::EdgeIter(traits::EdgeIter {
214 edge_iter: self.empty.iter(),
215 })
216 }
217 }
218
219 fn in_edges(&self, n: &T) -> traits::EdgeIterType<T, W> {
220 self.edges(n)
221 }
222
223 fn connected_components(&self) -> Vec<Vec<T>>
247 where
248 Self: Sized,
249 {
250 let mut visited = HashSet::new();
251 let mut components = vec![];
252
253 for node in self.nodes() {
254 if visited.contains(&node) {
255 continue;
256 }
257
258 let mut component = vec![node];
259
260 for (inner_node, _) in self.bfs(node) {
261 component.push(inner_node);
262 visited.insert(inner_node);
263 }
264
265 components.push(component);
266 }
267
268 components
269 }
270}
271
272impl<T, W> ArithmeticallyWeightedGraph<T, W> for UnGraph<T, W>
273where
274 T: Clone + Copy + Eq + Hash + PartialEq,
275 W: Clone
276 + Copy
277 + std::ops::Add<Output = W>
278 + std::ops::Sub<Output = W>
279 + PartialOrd
280 + Ord
281 + Default,
282{
283}
284
285impl<T, W> Default for UnGraph<T, W> {
286 fn default() -> Self {
287 UnGraph {
288 nodes: HashSet::new(),
289 edges: HashMap::new(),
290 empty: HashMap::new(),
291 }
292 }
293}
294
295#[derive(Debug, Clone)]
299pub struct UnGraphVecEdges<T, W> {
300 nodes: HashSet<T>,
301 edges: HashMap<T, Vec<(T, W)>>,
302
303 empty: Vec<(T, W)>,
304}
305
306impl<T, W> UnGraphVecEdges<T, W>
307where
308 T: Clone + Copy + Hash + Eq + PartialEq,
309 W: Clone + Copy,
310{
311 pub fn new() -> Self {
312 Self::default()
313 }
314
315 pub fn basic_cycles(&self) -> Vec<Vec<T>> {
342 let mut remaining_edges = self.all_edges();
343
344 let mut spanning_forest = UnGraph::default();
345 let mut visited = HashSet::new();
346
347 for node in self.nodes() {
348 if visited.contains(&node) {
349 continue;
350 }
351
352 let mut queue = VecDeque::new();
353 queue.push_back((node, node));
354
355 while let Some((previous_node, inner_node)) = queue.pop_front() {
356 if visited.contains(&inner_node) {
357 continue;
358 }
359
360 remaining_edges.remove(&(inner_node, previous_node));
361 remaining_edges.remove(&(previous_node, inner_node));
362 spanning_forest.add_edge(previous_node, inner_node, 1);
363
364 visited.insert(inner_node);
365
366 for (target, _) in self.edges(&inner_node) {
367 if visited.contains(&target) {
368 continue;
369 }
370
371 queue.push_back((inner_node, target));
372 }
373 }
374 }
375
376 let mut cycles = Vec::new();
377
378 for edge in remaining_edges {
379 if let Some(path) = spanning_forest.find_path(edge.0, edge.1) {
380 cycles.push(path);
381 }
382 }
383
384 cycles
385 }
386
387 pub fn all_edges(&self) -> HashSet<(T, T)> {
405 let mut edges = HashSet::new();
406
407 for (origin, destinations) in &self.edges {
408 for (dest, _) in destinations {
409 if edges.contains(&(*dest, *origin)) {
410 continue;
411 }
412 edges.insert((*origin, *dest));
413 }
414 }
415
416 edges
417 }
418}
419
420impl<T, W> GraphBuilding<T, W> for UnGraphVecEdges<T, W>
421where
422 T: Clone + Copy + Hash + Eq + PartialEq,
423 W: Clone + Copy,
424{
425 fn add_edge(&mut self, from: T, to: T, weight: W) {
426 self.edges.entry(from).or_default().push((to, weight));
427 self.edges.entry(to).or_default().push((from, weight));
428
429 self.nodes.insert(from);
430 self.nodes.insert(to);
431 }
432
433 fn add_node(&mut self, node: T) -> bool {
434 self.nodes.insert(node)
435 }
436
437 fn remove_edge(&mut self, from: T, to: T) -> Result<(), NodeNotFound> {
438 let edges_beginning_at_from = self.edges.get_mut(&from).ok_or(NodeNotFound)?;
439
440 edges_beginning_at_from.retain(|(target, _)| *target != to);
441
442 let edges_beginning_at_to = self.edges.get_mut(&to).ok_or(NodeNotFound)?;
443
444 edges_beginning_at_to.retain(|(target, _)| *target != from);
445
446 Ok(())
447 }
448
449 fn remove_node(&mut self, node: T) -> Result<(), NodeNotFound> {
450 if !self.nodes.remove(&node) {
451 return Err(NodeNotFound);
452 }
453
454 self.edges.remove_entry(&node);
455
456 for edges in self.edges.values_mut() {
457 edges.retain(|(target, _)| *target != node);
458 }
459
460 Ok(())
461 }
462
463 fn has_edge(&self, from: T, to: T) -> bool {
464 self.edges
465 .get(&from)
466 .map_or(false, |edges| edges.iter().any(|(target, _)| *target == to))
467 }
468}
469
470impl<T, W> Traversable<T, W> for UnGraphVecEdges<T, W>
471where
472 T: Clone + Copy + Hash + Eq + PartialEq,
473 W: Clone + Copy,
474{
475 fn nodes(&self) -> traits::NodeIter<'_, T> {
476 traits::NodeIter {
477 nodes_iter: self.nodes.iter(),
478 }
479 }
480
481 fn edge_weight(&self, from: T, to: T) -> Result<W, NodeNotFound> {
482 self.edges
483 .get(&from)
484 .ok_or(NodeNotFound)?
485 .iter()
486 .find_map(|(x, y)| (*x == to).then_some(*y))
487 .ok_or(NodeNotFound)
488 }
489
490 fn edges(&self, n: &T) -> traits::EdgeIterType<T, W> {
491 let edges = self.edges.get(n);
492
493 if let Some(edges) = edges {
494 traits::EdgeIterType::EdgeIterVec(traits::EdgeIterVec {
495 edge_iter: edges.iter(),
496 })
497 } else {
498 traits::EdgeIterType::EdgeIterVec(traits::EdgeIterVec {
499 edge_iter: self.empty.iter(),
500 })
501 }
502 }
503
504 fn in_edges(&self, n: &T) -> traits::EdgeIterType<T, W> {
505 self.edges(n)
506 }
507
508 fn connected_components(&self) -> Vec<Vec<T>>
532 where
533 Self: Sized,
534 {
535 let mut visited = HashSet::new();
536 let mut components = vec![];
537
538 for node in self.nodes() {
539 if visited.contains(&node) {
540 continue;
541 }
542
543 let mut component = vec![node];
544
545 for (inner_node, _) in self.bfs(node) {
546 component.push(inner_node);
547 visited.insert(inner_node);
548 }
549
550 components.push(component);
551 }
552
553 components
554 }
555}
556
557impl<T, W> ArithmeticallyWeightedGraph<T, W> for UnGraphVecEdges<T, W>
558where
559 T: Clone + Copy + Eq + Hash + PartialEq,
560 W: Clone
561 + Copy
562 + std::ops::Add<Output = W>
563 + std::ops::Sub<Output = W>
564 + PartialOrd
565 + Ord
566 + Default,
567{
568}
569
570impl<T, W> Default for UnGraphVecEdges<T, W> {
571 fn default() -> Self {
572 UnGraphVecEdges {
573 nodes: HashSet::new(),
574 edges: HashMap::new(),
575 empty: Vec::new(),
576 }
577 }
578}
579
580#[derive(Debug, Clone)]
584pub struct DiGraph<T, W> {
585 nodes: HashSet<T>,
586 edges: HashMap<T, HashMap<T, W>>,
587 in_edges: HashMap<T, HashMap<T, W>>,
588
589 empty: HashMap<T, W>,
590}
591
592impl<T, W> Default for DiGraph<T, W> {
593 fn default() -> Self {
594 DiGraph {
595 nodes: HashSet::new(),
596 edges: HashMap::new(),
597 in_edges: HashMap::new(),
598 empty: HashMap::new(),
599 }
600 }
601}
602
603impl<T, W> DiGraph<T, W>
604where
605 T: Clone + Copy + Eq + Hash + PartialEq,
606 W: Clone + Copy,
607{
608 pub fn new() -> Self {
609 Self::default()
610 }
611
612 fn bidir_find_path_filter_edges<G>(
613 &self,
614 from: T,
615 to: T,
616 predicate: G,
617 ) -> Option<Vec<(T, Orientation)>>
618 where
619 G: Fn(T, T, Orientation) -> bool,
620 {
621 let mut visited = HashSet::new();
622 let mut pairs = HashMap::new();
623 let mut queue = VecDeque::new();
624
625 queue.push_back((from, from, Orientation::Correct));
626
627 while let Some((prev, current, orientation)) = queue.pop_front() {
628 if visited.contains(¤t) {
629 continue;
630 }
631 visited.insert(current);
632 pairs.insert(current, (prev, orientation));
633
634 if current == to {
635 let mut node = (current, orientation);
636
637 let mut path = Vec::new();
638 while node.0 != from {
639 path.push((node.0, pairs[&node.0].1));
640
641 node = pairs[&node.0];
642 }
643
644 path.push((node.0, pairs[&node.0].1));
645
646 path.reverse();
647
648 return Some(path);
649 }
650
651 for (target, _) in self.edges(¤t) {
652 if visited.contains(&target) || !predicate(current, target, Orientation::Correct) {
653 continue;
654 }
655
656 queue.push_back((current, target, Orientation::Correct));
657 }
658 for (target, _) in self.in_edges(¤t) {
659 if visited.contains(&target) || !predicate(current, target, Orientation::Inverted) {
660 continue;
661 }
662
663 queue.push_back((current, target, Orientation::Inverted));
664 }
665 }
666
667 None
668 }
669}
670
671#[derive(Debug, Clone, Copy, PartialEq, Eq)]
672enum Orientation {
673 Correct,
674 Inverted,
675}
676
677impl<T, W> GraphBuilding<T, W> for DiGraph<T, W>
678where
679 T: Clone + Copy + Eq + Hash + PartialEq,
680 W: Clone + Copy,
681{
682 fn add_edge(&mut self, from: T, to: T, weight: W) {
683 self.edges.entry(from).or_default().insert(to, weight);
684 self.in_edges.entry(to).or_default().insert(from, weight);
685
686 self.add_node(from);
687 self.add_node(to);
688 }
689
690 fn add_node(&mut self, node: T) -> bool {
691 self.nodes.insert(node)
692 }
693
694 fn remove_edge(&mut self, from: T, to: T) -> Result<(), NodeNotFound> {
695 self.edges.get_mut(&from).ok_or(NodeNotFound)?.remove(&to);
696 self.in_edges
697 .get_mut(&to)
698 .ok_or(NodeNotFound)?
699 .remove(&from);
700
701 Ok(())
702 }
703
704 fn remove_node(&mut self, node: T) -> Result<(), NodeNotFound> {
705 if !self.nodes.remove(&node) {
706 return Err(NodeNotFound);
707 }
708
709 self.edges.remove_entry(&node);
710
711 for edges in self.edges.values_mut() {
712 edges.remove(&node);
713 }
714
715 for edges in self.in_edges.values_mut() {
716 edges.remove(&node);
717 }
718
719 Ok(())
720 }
721
722 fn has_edge(&self, from: T, to: T) -> bool {
723 self.edges
724 .get(&from)
725 .map_or(false, |edges| edges.contains_key(&to))
726 }
727}
728
729impl<T, W> Traversable<T, W> for DiGraph<T, W>
730where
731 T: Clone + Copy + Eq + Hash + PartialEq,
732 W: Clone + Copy,
733{
734 fn nodes(&self) -> traits::NodeIter<'_, T> {
735 traits::NodeIter {
736 nodes_iter: self.nodes.iter(),
737 }
738 }
739
740 fn edges(&self, n: &T) -> traits::EdgeIterType<T, W> {
741 let edges = self.edges.get(n);
742
743 if let Some(edges) = edges {
744 traits::EdgeIterType::EdgeIter(traits::EdgeIter {
745 edge_iter: edges.iter(),
746 })
747 } else {
748 traits::EdgeIterType::EdgeIter(traits::EdgeIter {
749 edge_iter: self.empty.iter(),
750 })
751 }
752 }
753
754 fn edge_weight(&self, from: T, to: T) -> Result<W, NodeNotFound> {
755 self.edges
756 .get(&from)
757 .ok_or(NodeNotFound)?
758 .get(&to)
759 .ok_or(NodeNotFound)
760 .copied()
761 }
762
763 fn in_edges(&self, n: &T) -> traits::EdgeIterType<T, W> {
764 let edges = self.in_edges.get(n);
765
766 if let Some(edges) = edges {
767 traits::EdgeIterType::EdgeIter(traits::EdgeIter {
768 edge_iter: edges.iter(),
769 })
770 } else {
771 traits::EdgeIterType::EdgeIter(traits::EdgeIter {
772 edge_iter: self.empty.iter(),
773 })
774 }
775 }
776}
777
778impl<T, W> ArithmeticallyWeightedGraph<T, W> for DiGraph<T, W>
779where
780 T: Clone + Copy + Eq + Hash + PartialEq,
781 W: Clone
782 + Copy
783 + std::ops::Add<Output = W>
784 + std::ops::Sub<Output = W>
785 + PartialOrd
786 + Ord
787 + Default,
788{
789 fn edmonds_karp(&self, source: T, sink: T) -> HashMap<(T, T), W> {
818 let flows = HashMap::new();
819
820 let mut residual_obtension = ResidualNetwork { flows, graph: self };
821
822 while let Some(path) = self.bidir_find_path_filter_edges(source, sink, |x, y, _| {
823 residual_obtension.get_residual_capacity(x, y) > W::default()
824 }) {
825 let residuals_in_path = path
826 .iter()
827 .zip(&path[1..])
828 .map(|(&(x, _), &(y, _))| residual_obtension.get_residual_capacity(x, y));
829
830 let min_res = residuals_in_path.min().expect("Path should not be empty");
831
832 path.iter().zip(&path[1..]).for_each(|(&(x, _), &(y, _))| {
833 residual_obtension
834 .flows
835 .entry((x, y))
836 .and_modify(|v| *v = *v + min_res)
837 .or_insert(min_res);
838 residual_obtension
839 .flows
840 .entry((y, x))
841 .and_modify(|v| *v = *v - min_res)
842 .or_insert(W::default() - min_res);
843 });
844
845 residual_obtension = ResidualNetwork {
846 flows: residual_obtension.flows,
847 graph: self,
848 };
849 }
850
851 residual_obtension.flows
852 }
853}
854
855struct ResidualNetwork<'a, T, W> {
856 flows: HashMap<(T, T), W>,
857 graph: &'a dyn Traversable<T, W>,
858}
859impl<'a, T, W> ResidualNetwork<'a, T, W>
860where
861 T: Clone + Copy + Eq + Hash + PartialEq,
862 W: Clone
863 + Copy
864 + std::ops::Add<Output = W>
865 + std::ops::Sub<Output = W>
866 + PartialOrd
867 + Ord
868 + Default,
869{
870 fn get_residual_capacity(&self, s: T, t: T) -> W {
871 self.graph.edge_weight(s, t).unwrap_or(W::default())
872 - self.flows.get(&(s, t)).copied().unwrap_or(W::default())
873 }
874}
875
876#[derive(Debug, Clone)]
880pub struct DiGraphVecEdges<T, W> {
881 nodes: HashSet<T>,
882 edges: HashMap<T, Vec<(T, W)>>,
883 in_edges: HashMap<T, Vec<(T, W)>>,
884
885 empty: Vec<(T, W)>,
886}
887
888impl<T, W> Default for DiGraphVecEdges<T, W> {
889 fn default() -> Self {
890 DiGraphVecEdges {
891 nodes: HashSet::new(),
892 edges: HashMap::new(),
893 in_edges: HashMap::new(),
894 empty: Vec::new(),
895 }
896 }
897}
898
899impl<T, W> DiGraphVecEdges<T, W>
900where
901 T: Clone + Copy + Eq + Hash + PartialEq,
902 W: Clone + Copy,
903{
904 pub fn new() -> Self {
905 Self::default()
906 }
907
908 fn bidir_find_path_filter_edges<G>(
909 &self,
910 from: T,
911 to: T,
912 predicate: G,
913 ) -> Option<Vec<(T, Orientation)>>
914 where
915 G: Fn(T, T, Orientation) -> bool,
916 {
917 let mut visited = HashSet::new();
918 let mut pairs = HashMap::new();
919 let mut queue = VecDeque::new();
920
921 queue.push_back((from, from, Orientation::Correct));
922
923 while let Some((prev, current, orientation)) = queue.pop_front() {
924 if visited.contains(¤t) {
925 continue;
926 }
927 visited.insert(current);
928 pairs.insert(current, (prev, orientation));
929
930 if current == to {
931 let mut node = (current, orientation);
932
933 let mut path = Vec::new();
934 while node.0 != from {
935 path.push((node.0, pairs[&node.0].1));
936
937 node = pairs[&node.0];
938 }
939
940 path.push((node.0, pairs[&node.0].1));
941
942 path.reverse();
943
944 return Some(path);
945 }
946
947 for (target, _) in self.edges(¤t) {
948 if visited.contains(&target) || !predicate(current, target, Orientation::Correct) {
949 continue;
950 }
951
952 queue.push_back((current, target, Orientation::Correct));
953 }
954 for (target, _) in self.in_edges(¤t) {
955 if visited.contains(&target) || !predicate(current, target, Orientation::Inverted) {
956 continue;
957 }
958
959 queue.push_back((current, target, Orientation::Inverted));
960 }
961 }
962
963 None
964 }
965}
966
967impl<T, W> GraphBuilding<T, W> for DiGraphVecEdges<T, W>
968where
969 T: Clone + Copy + Eq + Hash + PartialEq,
970 W: Clone + Copy,
971{
972 fn add_edge(&mut self, from: T, to: T, weight: W) {
973 self.edges.entry(from).or_default().push((to, weight));
974 self.in_edges.entry(to).or_default().push((from, weight));
975
976 self.nodes.insert(from);
977 self.nodes.insert(to);
978 }
979
980 fn add_node(&mut self, node: T) -> bool {
981 self.nodes.insert(node)
982 }
983
984 fn remove_edge(&mut self, from: T, to: T) -> Result<(), NodeNotFound> {
985 self.edges
986 .get_mut(&from)
987 .ok_or(NodeNotFound)?
988 .retain(|(node, _)| *node != to);
989
990 self.in_edges
991 .get_mut(&to)
992 .ok_or(NodeNotFound)?
993 .retain(|(node, _)| *node != from);
994
995 Ok(())
996 }
997
998 fn remove_node(&mut self, node: T) -> Result<(), NodeNotFound> {
999 if !self.nodes.remove(&node) {
1000 return Err(NodeNotFound);
1001 }
1002
1003 self.edges.remove_entry(&node);
1004
1005 for edges in self.edges.values_mut() {
1006 edges.retain(|(target, _)| *target != node);
1007 }
1008
1009 for edges in self.in_edges.values_mut() {
1010 edges.retain(|(target, _)| *target != node);
1011 }
1012
1013 Ok(())
1014 }
1015
1016 fn has_edge(&self, from: T, to: T) -> bool {
1017 self.edges
1018 .get(&from)
1019 .map_or(false, |edges| edges.iter().any(|(node, _)| *node == to))
1020 }
1021}
1022
1023impl<T, W> Traversable<T, W> for DiGraphVecEdges<T, W>
1024where
1025 T: Clone + Copy + Eq + Hash + PartialEq,
1026 W: Clone + Copy,
1027{
1028 fn nodes(&self) -> traits::NodeIter<'_, T> {
1029 traits::NodeIter {
1030 nodes_iter: self.nodes.iter(),
1031 }
1032 }
1033
1034 fn edges(&self, n: &T) -> traits::EdgeIterType<T, W> {
1035 let edges = self.edges.get(n);
1036
1037 if let Some(edges) = edges {
1038 traits::EdgeIterType::EdgeIterVec(traits::EdgeIterVec {
1039 edge_iter: edges.iter(),
1040 })
1041 } else {
1042 traits::EdgeIterType::EdgeIterVec(traits::EdgeIterVec {
1043 edge_iter: self.empty.iter(),
1044 })
1045 }
1046 }
1047
1048 fn edge_weight(&self, from: T, to: T) -> Result<W, NodeNotFound> {
1049 self.edges
1050 .get(&from)
1051 .ok_or(NodeNotFound)?
1052 .iter()
1053 .find_map(|(x, y)| (*x == to).then_some(*y))
1054 .ok_or(NodeNotFound)
1055 }
1056
1057 fn in_edges(&self, n: &T) -> traits::EdgeIterType<T, W> {
1058 let edges = self.in_edges.get(n);
1059
1060 if let Some(edges) = edges {
1061 traits::EdgeIterType::EdgeIterVec(traits::EdgeIterVec {
1062 edge_iter: edges.iter(),
1063 })
1064 } else {
1065 traits::EdgeIterType::EdgeIterVec(traits::EdgeIterVec {
1066 edge_iter: self.empty.iter(),
1067 })
1068 }
1069 }
1070}
1071
1072impl<T, W> ArithmeticallyWeightedGraph<T, W> for DiGraphVecEdges<T, W>
1073where
1074 T: Clone + Copy + Eq + Hash + PartialEq,
1075 W: Clone
1076 + Copy
1077 + std::ops::Add<Output = W>
1078 + std::ops::Sub<Output = W>
1079 + PartialOrd
1080 + Ord
1081 + Default,
1082{
1083 fn edmonds_karp(&self, source: T, sink: T) -> HashMap<(T, T), W> {
1112 let flows = HashMap::new();
1113
1114 let mut residual_obtension = ResidualNetwork { flows, graph: self };
1115
1116 while let Some(path) = self.bidir_find_path_filter_edges(source, sink, |x, y, _| {
1117 residual_obtension.get_residual_capacity(x, y) > W::default()
1118 }) {
1119 let residuals_in_path = path
1120 .iter()
1121 .zip(&path[1..])
1122 .map(|(&(x, _), &(y, _))| residual_obtension.get_residual_capacity(x, y));
1123
1124 let min_res = residuals_in_path.min().expect("Path should not be empty");
1125
1126 path.iter().zip(&path[1..]).for_each(|(&(x, _), &(y, _))| {
1127 residual_obtension
1128 .flows
1129 .entry((x, y))
1130 .and_modify(|v| *v = *v + min_res)
1131 .or_insert(min_res);
1132 residual_obtension
1133 .flows
1134 .entry((y, x))
1135 .and_modify(|v| *v = *v - min_res)
1136 .or_insert(W::default() - min_res);
1137 });
1138
1139 residual_obtension = ResidualNetwork {
1140 flows: residual_obtension.flows,
1141 graph: self,
1142 };
1143 }
1144
1145 residual_obtension.flows
1146 }
1147}
1148
1149#[cfg(test)]
1150mod tests {
1151 use std::vec;
1152
1153 use super::*;
1154
1155 #[test]
1156 fn test_derives() {
1157 let g = UnGraph::<(), ()>::new();
1158 _ = g.clone();
1159 dbg!(g);
1160
1161 let g = DiGraph::<(), ()>::new();
1162 _ = g.clone();
1163 dbg!(g);
1164
1165 let g = UnGraphVecEdges::<(), ()>::new();
1166 _ = g.clone();
1167 dbg!(g);
1168
1169 let g = DiGraphVecEdges::<(), ()>::new();
1170 _ = g.clone();
1171 dbg!(g);
1172 }
1173
1174 #[test]
1175 fn test_dijkstra() {
1176 let mut graph = UnGraph::default();
1177
1178 graph.add_edge(1, 2, 3);
1179 graph.add_edge(2, 3, 10);
1180 graph.add_edge(1, 3, 15);
1181
1182 assert_eq!(graph.dijkstra(1, 3), Some(13));
1183 assert_eq!(graph.dijkstra_with_path(1, 3).unwrap().0, vec![1, 2, 3]);
1184
1185 graph.add_edge(1, 4, 7);
1186 graph.add_edge(4, 3, 5);
1187
1188 assert_eq!(graph.dijkstra(1, 3), Some(12));
1189 assert_eq!(graph.dijkstra_with_path(1, 3).unwrap().0, vec![1, 4, 3]);
1190
1191 assert!(graph.dijkstra(1, 9).is_none());
1192 assert!(graph.dijkstra_with_path(1, 9).is_none());
1193 }
1194
1195 #[test]
1196 fn test_dijkstra_directed() {
1197 let mut graph = DiGraph::default();
1198
1199 graph.add_edge(1, 2, 3);
1200 graph.add_edge(2, 3, 10);
1201 graph.add_edge(1, 3, 15);
1202
1203 assert_eq!(graph.dijkstra(1, 3), Some(13));
1204 assert_eq!(graph.dijkstra(3, 1), None);
1205
1206 graph.add_edge(1, 4, 7);
1207 graph.add_edge(4, 3, 5);
1208
1209 assert_eq!(graph.dijkstra(1, 3), Some(12));
1210 assert_eq!(graph.dijkstra(3, 1), None);
1211 }
1212
1213 #[test]
1214 fn test_bfs() {
1215 let mut graph = UnGraph::default();
1216
1217 graph.add_edge(1, 2, 3);
1218 graph.add_edge(2, 3, 10);
1219
1220 assert_eq!(graph.bfs(1).find(|x| x.0 == 3).unwrap(), (3, 2));
1221
1222 graph.add_edge(1, 3, 15);
1223
1224 assert_eq!(graph.bfs(1).find(|x| x.0 == 3), Some((3, 1)));
1225 }
1226
1227 #[test]
1228 fn test_dfs() {
1229 let mut graph = UnGraph::default();
1230
1231 graph.add_edge(1, 2, 3);
1232 graph.add_edge(2, 3, 10);
1233
1234 assert_eq!(graph.dfs(1).find(|x| x.0 == 3).unwrap(), (3, 2));
1235
1236 graph.add_edge(1, 3, 15);
1237
1238 assert_eq!(graph.dfs(1).count(), 3);
1239 }
1240
1241 #[test]
1242 fn test_bfs2() {
1243 let mut graph = UnGraph::default();
1244
1245 graph.add_edge(1, 2, 3);
1246 graph.add_edge(2, 3, 10);
1247 graph.add_edge(1, 3, 15);
1248 graph.add_edge(3, 4, 4);
1249 graph.add_edge(4, 5, 7);
1250 graph.add_edge(1, 10, 3);
1251
1252 let values: Vec<(i32, usize)> = graph.bfs(1).collect();
1253
1254 assert_eq!(values.len(), 6);
1255 }
1256
1257 #[test]
1258 fn test_find_path() {
1259 let mut graph = UnGraph::default();
1260
1261 graph.add_edge(1, 2, ());
1262 graph.add_edge(2, 3, ());
1263 graph.add_edge(3, 4, ());
1264
1265 graph.add_edge(1, 5, ());
1266 graph.add_edge(5, 3, ());
1267 graph.add_edge(3, 4, ());
1268
1269 let path = graph.find_path(1, 4).unwrap();
1270
1271 assert_eq!(path.len(), 4);
1272
1273 assert!(graph.find_path(1, 7).is_none());
1274 }
1275
1276 #[test]
1277 fn test_find_path_filter_edges() {
1278 let mut graph = UnGraph::default();
1279
1280 graph.add_edge(1, 2, ());
1281 graph.add_edge(2, 3, ());
1282 graph.add_edge(3, 4, ());
1283 graph.add_edge(4, 5, ());
1284
1285 graph.add_edge(1, 7, ());
1286 graph.add_edge(7, 5, ());
1287
1288 let path = graph.find_path(1, 5).unwrap();
1289
1290 assert_eq!(path, vec![1, 7, 5]);
1291
1292 let path = graph
1293 .find_path_filter_edges(1, 5, |x, y| (x, y) != (1, 7))
1294 .unwrap();
1295
1296 assert_eq!(path, vec![1, 2, 3, 4, 5]);
1297 }
1298
1299 #[test]
1300 fn test_dijkstra_str() {
1301 let mut graph = DiGraph::default();
1302
1303 graph.add_edge("a", "b", 123);
1304 graph.add_edge("b", "c", 43);
1305 graph.add_edge("c", "d", 62);
1306
1307 graph.add_edge("a", "d", 253);
1308
1309 assert_eq!(graph.dijkstra("a", "d").unwrap(), 228);
1310 }
1311
1312 #[test]
1313 fn test_a_star() {
1314 let mut graph = DiGraph::default();
1315
1316 graph.add_edge(1, 2, 12);
1317 graph.add_edge(2, 3, 13);
1318 graph.add_edge(3, 4, 8);
1319
1320 graph.add_edge(1, 4, 40);
1321
1322 assert_eq!(graph.a_star(1, 4, |x| 4 - x).unwrap(), 33);
1323 assert!(graph.a_star(1, 10, |x| 10 - x).is_none());
1324 }
1325
1326 #[test]
1327 fn test_a_star_with_path() {
1328 let mut graph = DiGraph::default();
1329
1330 graph.add_edge(1, 2, 12);
1331 graph.add_edge(2, 3, 13);
1332 graph.add_edge(3, 4, 8);
1333
1334 graph.add_edge(1, 4, 40);
1335
1336 assert_eq!(
1337 graph.a_star_with_path(1, 4, |x| 4 - x).unwrap().0,
1338 vec![1, 2, 3, 4]
1339 );
1340 assert!(graph.a_star_with_path(1, 10, |x| 10 - x).is_none());
1341
1342 let mut graph = DiGraph::default();
1343
1344 graph.add_edge(1, 2, 6);
1345 graph.add_edge(2, 3, 10);
1346 graph.add_edge(1, 3, 13);
1347 graph.add_edge(3, 4, 40);
1348
1349 assert_eq!(
1350 graph.a_star_with_path(1, 4, |_| 0).unwrap().0,
1351 vec![1, 3, 4]
1352 );
1353 }
1354
1355 #[test]
1356 fn test_connected_components() {
1357 let mut graph = DiGraph::default();
1358
1359 graph.add_edge(1, 2, 12);
1360 graph.add_edge(2, 3, 13);
1361 graph.add_edge(3, 4, 8);
1362
1363 graph.add_edge(5, 6, 40);
1364
1365 assert_eq!(graph.connected_components().len(), 6);
1366
1367 graph.add_edge(4, 1, 8);
1368
1369 assert_eq!(graph.connected_components().len(), 3);
1370
1371 let mut graph = UnGraph::default();
1372
1373 graph.add_edge(1, 2, 12);
1374 graph.add_edge(2, 3, 13);
1375 graph.add_edge(3, 4, 8);
1376
1377 graph.add_edge(5, 6, 40);
1378
1379 assert_eq!(graph.connected_components().len(), 2);
1380
1381 let mut graph = UnGraphVecEdges::default();
1382
1383 graph.add_edge(1, 2, 12);
1384 graph.add_edge(2, 3, 13);
1385 graph.add_edge(3, 4, 8);
1386
1387 graph.add_edge(5, 6, 40);
1388
1389 assert_eq!(graph.connected_components().len(), 2);
1390 }
1391
1392 #[test]
1393 fn test_connected_components2() {
1394 let mut graph = DiGraph::default();
1395
1396 for i in 0..15 {
1397 for j in (i + 1)..15 {
1398 graph.add_edge(i, j, ())
1399 }
1400 }
1401
1402 assert_eq!(graph.connected_components().len(), 15);
1403
1404 let mut graph = UnGraph::default();
1405
1406 for i in 0..15 {
1407 for j in (i + 1)..15 {
1408 graph.add_edge(i, j, ())
1409 }
1410 }
1411
1412 assert_eq!(graph.connected_components().len(), 1);
1413 }
1414
1415 #[test]
1416 fn test_dfs_post_order() {
1417 let mut graph = UnGraph::default();
1418
1419 graph.add_edge(1, 2, ());
1420 graph.add_edge(1, 3, ());
1421
1422 graph.add_edge(2, 4, ());
1423 graph.add_edge(2, 5, ());
1424
1425 graph.add_edge(3, 6, ());
1426 graph.add_edge(6, 7, ());
1427 graph.add_edge(7, 8, ());
1428
1429 graph.add_edge(5, 9, ());
1430 graph.add_edge(5, 10, ());
1431
1432 let dfs_post_order: Vec<_> = graph.dfs_post_order(1).map(|x| x.0).collect();
1433
1434 assert_eq!(dfs_post_order.len(), 10);
1435 }
1436
1437 #[test]
1438 fn test_cycles() {
1439 let mut graph = UnGraph::default();
1440
1441 graph.add_edge(1, 2, ());
1442 graph.add_edge(2, 3, ());
1443 graph.add_edge(3, 4, ());
1444
1445 let cycles = graph.basic_cycles();
1446 assert_eq!(cycles.len(), 0);
1447
1448 graph.add_edge(4, 1, ());
1449 let cycles = graph.basic_cycles();
1450 assert_eq!(cycles.len(), 1);
1451 }
1452
1453 #[test]
1454 fn test_cycles2() {
1455 let mut graph = UnGraph::default();
1456
1457 graph.add_edge(1, 2, ());
1458 graph.add_edge(2, 3, ());
1459 graph.add_edge(3, 4, ());
1460 graph.add_edge(4, 1, ());
1461
1462 graph.add_edge(2, 5, ());
1463
1464 graph.add_edge(5, 6, ());
1465 graph.add_edge(6, 7, ());
1466 graph.add_edge(7, 5, ());
1467
1468 let cycles = graph.basic_cycles();
1469 assert_eq!(cycles.len(), 2);
1470
1471 graph.remove_edge(6, 7).unwrap();
1472
1473 let cycles = graph.basic_cycles();
1474 assert_eq!(cycles.len(), 1);
1475
1476 let mut graph = UnGraphVecEdges::default();
1477
1478 graph.add_edge(1, 2, ());
1479 graph.add_edge(2, 3, ());
1480 graph.add_edge(3, 4, ());
1481 graph.add_edge(4, 1, ());
1482
1483 graph.add_edge(2, 5, ());
1484
1485 graph.add_edge(5, 6, ());
1486 graph.add_edge(6, 7, ());
1487 graph.add_edge(7, 5, ());
1488
1489 let cycles = graph.basic_cycles();
1490 assert_eq!(cycles.len(), 2);
1491
1492 graph.remove_edge(6, 7).unwrap();
1493
1494 let cycles = graph.basic_cycles();
1495 assert_eq!(cycles.len(), 1);
1496 }
1497
1498 #[test]
1499 fn ungraph_maintenance() {
1500 let mut graph = UnGraph::<i32, ()>::new();
1501 graph.add_node(0);
1502
1503 assert_eq!(graph.nodes().count(), 1);
1504
1505 graph.remove_node(0).unwrap();
1506 assert_eq!(graph.nodes().count(), 0);
1507 assert!(graph.remove_node(0).is_err());
1508
1509 assert_eq!(graph.edges(&0).count(), 0);
1510 assert_eq!(graph.in_edges(&0).count(), 0);
1511
1512 assert!(!graph.has_edge(0, 1));
1513
1514 graph.add_edge(0, 1, ());
1515 assert!(graph.has_edge(0, 1));
1516 graph.remove_node(0).unwrap();
1517 assert!(!graph.has_edge(0, 1));
1518
1519 let mut graph = UnGraphVecEdges::<i32, ()>::new();
1520 graph.add_node(0);
1521
1522 assert_eq!(graph.nodes().count(), 1);
1523
1524 graph.remove_node(0).unwrap();
1525 assert_eq!(graph.nodes().count(), 0);
1526 assert!(graph.remove_node(0).is_err());
1527
1528 assert_eq!(graph.edges(&0).count(), 0);
1529 assert_eq!(graph.in_edges(&0).count(), 0);
1530
1531 assert!(!graph.has_edge(0, 1));
1532
1533 graph.add_edge(0, 1, ());
1534 assert!(graph.has_edge(0, 1));
1535 graph.remove_node(0).unwrap();
1536 assert!(!graph.has_edge(0, 1));
1537 }
1538
1539 #[test]
1540 fn digraph_maintenance() {
1541 let mut graph = DiGraph::<i32, ()>::new();
1542 graph.add_node(0);
1543
1544 assert_eq!(graph.nodes().count(), 1);
1545
1546 graph.remove_node(0).unwrap();
1547 assert_eq!(graph.nodes().count(), 0);
1548 assert!(graph.remove_node(0).is_err());
1549
1550 assert_eq!(graph.edges(&0).count(), 0);
1551 assert_eq!(graph.in_edges(&0).count(), 0);
1552
1553 assert!(!graph.has_edge(0, 1));
1554
1555 graph.add_edge(0, 1, ());
1556 assert!(graph.has_edge(0, 1));
1557 graph.remove_node(0).unwrap();
1558 assert!(!graph.has_edge(0, 1));
1559
1560 graph.add_edge(0, 1, ());
1561 graph.remove_edge(0, 1).unwrap();
1562
1563 assert!(!graph.has_edge(0, 1));
1564 assert!(graph.nodes().any(|x| x == 0));
1565 assert!(graph.nodes().any(|x| x == 1));
1566
1567 graph.add_edge(3, 4, ());
1568 graph.add_edge(4, 5, ());
1569 graph.add_edge(4, 6, ());
1570
1571 assert!(graph.has_edge(3, 4));
1572 assert!(graph.has_edge(4, 5));
1573 assert!(graph.has_edge(4, 6));
1574 assert!(!graph.has_edge(4, 3));
1575 assert!(!graph.has_edge(5, 4));
1576 assert!(!graph.has_edge(6, 4));
1577
1578 assert_eq!(graph.edges(&4).count(), 2);
1579 assert_eq!(graph.in_edges(&4).count(), 1);
1580
1581 graph.remove_node(4).unwrap();
1582
1583 assert!(!graph.has_edge(3, 4));
1584 assert!(!graph.has_edge(4, 5));
1585 assert!(!graph.has_edge(4, 6));
1586
1587 let mut graph = DiGraphVecEdges::<i32, ()>::new();
1588 graph.add_node(0);
1589
1590 assert_eq!(graph.nodes().count(), 1);
1591
1592 graph.remove_node(0).unwrap();
1593 assert_eq!(graph.nodes().count(), 0);
1594 assert!(graph.remove_node(0).is_err());
1595
1596 assert_eq!(graph.edges(&0).count(), 0);
1597 assert_eq!(graph.in_edges(&0).count(), 0);
1598
1599 assert!(!graph.has_edge(0, 1));
1600
1601 graph.add_edge(0, 1, ());
1602 assert!(graph.has_edge(0, 1));
1603 graph.remove_node(0).unwrap();
1604 assert!(!graph.has_edge(0, 1));
1605
1606 graph.add_edge(0, 1, ());
1607 graph.remove_edge(0, 1).unwrap();
1608
1609 assert!(!graph.has_edge(0, 1));
1610 assert!(graph.nodes().any(|x| x == 0));
1611 assert!(graph.nodes().any(|x| x == 1));
1612
1613 graph.add_edge(3, 4, ());
1614 graph.add_edge(4, 5, ());
1615 graph.add_edge(4, 6, ());
1616
1617 assert!(graph.has_edge(3, 4));
1618 assert!(graph.has_edge(4, 5));
1619 assert!(graph.has_edge(4, 6));
1620 assert!(!graph.has_edge(4, 3));
1621 assert!(!graph.has_edge(5, 4));
1622 assert!(!graph.has_edge(6, 4));
1623
1624 assert_eq!(graph.edges(&4).count(), 2);
1625 assert_eq!(graph.in_edges(&4).count(), 1);
1626
1627 graph.remove_node(4).unwrap();
1628
1629 assert!(!graph.has_edge(3, 4));
1630 assert!(!graph.has_edge(4, 5));
1631 assert!(!graph.has_edge(4, 6));
1632 }
1633
1634 #[test]
1635 fn test_bidir_find_path() {
1636 let mut digraph = DiGraph::new();
1637
1638 digraph.add_edge("B", "A", ());
1639 digraph.add_edge("B", "C", ());
1640
1641 let path = digraph
1642 .bidir_find_path_filter_edges("A", "C", |_, _, _| true)
1643 .unwrap();
1644
1645 assert_eq!(
1646 path,
1647 [
1648 ("A", Orientation::Correct),
1649 ("B", Orientation::Inverted),
1650 ("C", Orientation::Correct)
1651 ]
1652 )
1653 }
1654
1655 #[test]
1656 fn test_edmonds_karp() {
1657 let mut g = UnGraph::new();
1658
1659 g.add_edge("A", "B", 1000);
1660 g.add_edge("A", "C", 1000);
1661
1662 g.add_edge("B", "C", 1);
1663
1664 g.add_edge("B", "D", 1000);
1665 g.add_edge("C", "D", 1000);
1666
1667 let flows = g.edmonds_karp("A", "D");
1668
1669 assert_eq!(*flows.get(&("A", "B")).unwrap(), 1000);
1670 assert_eq!(*flows.get(&("A", "C")).unwrap(), 1000);
1671
1672 assert_eq!(*flows.get(&("B", "C")).unwrap_or(&0), 0);
1673
1674 assert_eq!(*flows.get(&("B", "D")).unwrap(), 1000);
1675 assert_eq!(*flows.get(&("C", "D")).unwrap(), 1000);
1676
1677 let mut g = UnGraph::new();
1678
1679 g.add_edge("C", "A", 3);
1680 g.add_edge("C", "D", 1);
1681 g.add_edge("C", "E", 2);
1682
1683 g.add_edge("B", "C", 4);
1684
1685 g.add_edge("A", "B", 3);
1686 g.add_edge("A", "D", 3);
1687
1688 g.add_edge("D", "E", 2);
1689 g.add_edge("D", "F", 6);
1690
1691 g.add_edge("E", "G", 1);
1692 g.add_edge("E", "B", 1);
1693
1694 g.add_edge("F", "G", 9);
1695
1696 let flows = g.edmonds_karp("A", "G");
1697
1698 assert_eq!(*flows.get(&("E", "G")).unwrap_or(&0), 1);
1699 assert_eq!(*flows.get(&("F", "G")).unwrap_or(&0), 6);
1700
1701 let mut g = UnGraphVecEdges::new();
1702
1703 g.add_edge("C", "A", 3);
1704 g.add_edge("C", "D", 1);
1705 g.add_edge("C", "E", 2);
1706
1707 g.add_edge("B", "C", 4);
1708
1709 g.add_edge("A", "B", 3);
1710 g.add_edge("A", "D", 3);
1711
1712 g.add_edge("D", "E", 2);
1713 g.add_edge("D", "F", 6);
1714
1715 g.add_edge("E", "G", 1);
1716 g.add_edge("E", "B", 1);
1717
1718 g.add_edge("F", "G", 9);
1719
1720 let flows = g.edmonds_karp("A", "G");
1721
1722 assert_eq!(*flows.get(&("E", "G")).unwrap_or(&0), 1);
1723 assert_eq!(*flows.get(&("F", "G")).unwrap_or(&0), 6);
1724 }
1725
1726 #[test]
1727 fn test_edmonds_karp_directed() {
1728 let mut g = DiGraph::new();
1729
1730 g.add_edge("C", "A", 3);
1731 g.add_edge("C", "D", 1);
1732 g.add_edge("C", "E", 2);
1733
1734 g.add_edge("B", "C", 4);
1735
1736 g.add_edge("A", "B", 3);
1737 g.add_edge("A", "D", 3);
1738
1739 g.add_edge("D", "E", 2);
1740 g.add_edge("D", "F", 6);
1741
1742 g.add_edge("E", "G", 1);
1743 g.add_edge("E", "B", 1);
1744
1745 g.add_edge("F", "G", 9);
1746
1747 let flows = g.edmonds_karp("A", "G");
1748
1749 assert_eq!(*flows.get(&("E", "G")).unwrap_or(&0), 1);
1750 assert_eq!(*flows.get(&("F", "G")).unwrap_or(&0), 4);
1751
1752 let mut g = DiGraphVecEdges::new();
1754
1755 g.add_edge("C", "A", 3);
1756 g.add_edge("C", "D", 1);
1757 g.add_edge("C", "E", 2);
1758
1759 g.add_edge("B", "C", 4);
1760
1761 g.add_edge("A", "B", 3);
1762 g.add_edge("A", "D", 3);
1763
1764 g.add_edge("D", "E", 2);
1765 g.add_edge("D", "F", 6);
1766
1767 g.add_edge("E", "G", 1);
1768 g.add_edge("E", "B", 1);
1769
1770 g.add_edge("F", "G", 9);
1771
1772 let flows = g.edmonds_karp("A", "G");
1773
1774 println!("{:#?}", flows);
1775
1776 assert_eq!(*flows.get(&("E", "G")).unwrap_or(&0), 1);
1777 assert_eq!(*flows.get(&("F", "G")).unwrap_or(&0), 4);
1778 }
1779}