rust_igraph/algorithms/operators/
is_same_graph.rs1use crate::core::Graph;
15
16#[must_use]
55pub fn is_same_graph(g1: &Graph, g2: &Graph) -> bool {
56 if g1.vcount() != g2.vcount() {
57 return false;
58 }
59 if g1.ecount() != g2.ecount() {
60 return false;
61 }
62 if g1.is_directed() != g2.is_directed() {
63 return false;
64 }
65
66 let m = g1.ecount();
67 if m == 0 {
68 return true;
69 }
70
71 let Ok(m_u32) = u32::try_from(m) else {
78 return false;
79 };
80 let e1_result: Result<Vec<(u32, u32)>, _> = (0..m_u32).map(|e| g1.edge(e)).collect();
81 let e2_result: Result<Vec<(u32, u32)>, _> = (0..m_u32).map(|e| g2.edge(e)).collect();
82 let (Ok(mut e1), Ok(mut e2)) = (e1_result, e2_result) else {
83 return false;
84 };
85 e1.sort_unstable();
88 e2.sort_unstable();
89 e1 == e2
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95 use crate::core::Graph;
96
97 #[test]
98 fn same_graph_identical_construction() {
99 let mut g1 = Graph::with_vertices(3);
100 g1.add_edges(vec![(0u32, 1u32), (1, 2)]).unwrap();
101 let mut g2 = Graph::with_vertices(3);
102 g2.add_edges(vec![(0u32, 1u32), (1, 2)]).unwrap();
103 assert!(is_same_graph(&g1, &g2));
104 }
105
106 #[test]
107 fn same_graph_edge_order_does_not_matter() {
108 let mut g1 = Graph::with_vertices(3);
109 g1.add_edges(vec![(0u32, 1u32), (1, 2)]).unwrap();
110 let mut g2 = Graph::with_vertices(3);
111 g2.add_edges(vec![(1u32, 2u32), (0, 1)]).unwrap();
112 assert!(is_same_graph(&g1, &g2));
113 }
114
115 #[test]
116 fn same_graph_undirected_endpoint_orientation_does_not_matter() {
117 let mut g1 = Graph::with_vertices(2);
118 g1.add_edge(0, 1).unwrap();
119 let mut g2 = Graph::with_vertices(2);
120 g2.add_edge(1, 0).unwrap();
121 assert!(is_same_graph(&g1, &g2));
122 }
123
124 #[test]
125 fn different_vcount_not_same() {
126 let mut g1 = Graph::with_vertices(3);
127 g1.add_edge(0, 1).unwrap();
128 let mut g2 = Graph::with_vertices(4);
129 g2.add_edge(0, 1).unwrap();
130 assert!(!is_same_graph(&g1, &g2));
131 }
132
133 #[test]
134 fn different_ecount_not_same() {
135 let mut g1 = Graph::with_vertices(3);
136 g1.add_edge(0, 1).unwrap();
137 let mut g2 = Graph::with_vertices(3);
138 g2.add_edges(vec![(0u32, 1u32), (1, 2)]).unwrap();
139 assert!(!is_same_graph(&g1, &g2));
140 }
141
142 #[test]
143 fn directed_vs_undirected_not_same() {
144 let mut g1 = Graph::new(3, true).unwrap();
145 g1.add_edge(0, 1).unwrap();
146 let mut g2 = Graph::with_vertices(3);
147 g2.add_edge(0, 1).unwrap();
148 assert!(!is_same_graph(&g1, &g2));
149 }
150
151 #[test]
152 fn directed_edge_direction_matters() {
153 let mut g1 = Graph::new(2, true).unwrap();
155 g1.add_edge(0, 1).unwrap();
156 let mut g2 = Graph::new(2, true).unwrap();
157 g2.add_edge(1, 0).unwrap();
158 assert!(!is_same_graph(&g1, &g2));
159 }
160
161 #[test]
162 fn parallel_edges_multiplicity_matters() {
163 let mut g1 = Graph::with_vertices(2);
165 g1.add_edges(vec![(0u32, 1u32), (0, 1)]).unwrap();
166 let mut g2 = Graph::with_vertices(2);
167 g2.add_edges(vec![(0u32, 1u32), (0, 1)]).unwrap();
168 assert!(is_same_graph(&g1, &g2));
169 let mut g3 = Graph::with_vertices(2);
171 g3.add_edge(0, 1).unwrap();
172 assert!(!is_same_graph(&g1, &g3));
173 }
174
175 #[test]
176 fn self_loop_recognised_as_same() {
177 let mut g1 = Graph::with_vertices(2);
178 g1.add_edges(vec![(0u32, 0u32), (0, 1)]).unwrap();
179 let mut g2 = Graph::with_vertices(2);
180 g2.add_edges(vec![(0u32, 1u32), (0, 0)]).unwrap();
181 assert!(is_same_graph(&g1, &g2));
182 }
183
184 #[test]
185 fn empty_graphs_are_same_when_vcount_matches() {
186 let g1 = Graph::with_vertices(0);
187 let g2 = Graph::with_vertices(0);
188 assert!(is_same_graph(&g1, &g2));
189 let g3 = Graph::with_vertices(5);
190 let g4 = Graph::with_vertices(5);
191 assert!(is_same_graph(&g3, &g4));
192 }
193
194 #[test]
195 fn isomorphic_but_different_edge_sets_not_same() {
196 let mut g1 = Graph::with_vertices(3);
199 g1.add_edges(vec![(0u32, 1u32), (1, 2)]).unwrap();
200 let mut g2 = Graph::with_vertices(3);
201 g2.add_edges(vec![(0u32, 2u32), (1, 2)]).unwrap();
202 assert!(!is_same_graph(&g1, &g2));
203 }
204
205 #[test]
206 fn reflexivity() {
207 let mut g = Graph::with_vertices(4);
208 g.add_edges(vec![(0u32, 1u32), (0, 2), (1, 3)]).unwrap();
209 let g2 = g.clone();
210 assert!(is_same_graph(&g, &g2));
211 }
212}