rust_igraph/algorithms/properties/
satisfies_ore.rs1use crate::core::{Graph, IgraphResult};
12
13pub fn satisfies_ore(graph: &Graph) -> IgraphResult<bool> {
44 if graph.is_directed() {
45 return Ok(false);
46 }
47
48 let n = graph.vcount();
49 if n < 3 {
50 return Ok(false);
51 }
52
53 let n_usize = n as usize;
54
55 let mut degrees = Vec::with_capacity(n_usize);
57 for v in 0..n {
58 degrees.push(graph.degree(v)?);
59 }
60
61 let mut adj = vec![vec![false; n_usize]; n_usize];
63 for v in 0..n {
64 let nbrs = graph.neighbors(v)?;
65 for &w in &nbrs {
66 adj[v as usize][w as usize] = true;
67 }
68 }
69
70 for u in 0..n_usize {
72 for v in (u + 1)..n_usize {
73 if !adj[u][v] && degrees[u] + degrees[v] < n_usize {
74 return Ok(false);
75 }
76 }
77 }
78
79 Ok(true)
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 #[test]
87 fn empty_graph() {
88 let g = Graph::with_vertices(0);
89 assert!(!satisfies_ore(&g).unwrap());
90 }
91
92 #[test]
93 fn single_vertex() {
94 let g = Graph::with_vertices(1);
95 assert!(!satisfies_ore(&g).unwrap());
96 }
97
98 #[test]
99 fn two_vertices() {
100 let mut g = Graph::with_vertices(2);
101 g.add_edge(0, 1).unwrap();
102 assert!(!satisfies_ore(&g).unwrap());
103 }
104
105 #[test]
106 fn triangle() {
107 let mut g = Graph::with_vertices(3);
109 g.add_edge(0, 1).unwrap();
110 g.add_edge(1, 2).unwrap();
111 g.add_edge(2, 0).unwrap();
112 assert!(satisfies_ore(&g).unwrap());
113 }
114
115 #[test]
116 fn complete_k4() {
117 let mut g = Graph::with_vertices(4);
118 for i in 0..4u32 {
119 for j in (i + 1)..4 {
120 g.add_edge(i, j).unwrap();
121 }
122 }
123 assert!(satisfies_ore(&g).unwrap());
124 }
125
126 #[test]
127 fn c4() {
128 let mut g = Graph::with_vertices(4);
131 g.add_edge(0, 1).unwrap();
132 g.add_edge(1, 2).unwrap();
133 g.add_edge(2, 3).unwrap();
134 g.add_edge(3, 0).unwrap();
135 assert!(satisfies_ore(&g).unwrap());
136 }
137
138 #[test]
139 fn c5_fails() {
140 let mut g = Graph::with_vertices(5);
142 g.add_edge(0, 1).unwrap();
143 g.add_edge(1, 2).unwrap();
144 g.add_edge(2, 3).unwrap();
145 g.add_edge(3, 4).unwrap();
146 g.add_edge(4, 0).unwrap();
147 assert!(!satisfies_ore(&g).unwrap());
148 }
149
150 #[test]
151 fn path_p4_fails() {
152 let mut g = Graph::with_vertices(4);
154 g.add_edge(0, 1).unwrap();
155 g.add_edge(1, 2).unwrap();
156 g.add_edge(2, 3).unwrap();
157 assert!(!satisfies_ore(&g).unwrap());
158 }
159
160 #[test]
161 fn star_fails() {
162 let mut g = Graph::with_vertices(5);
163 g.add_edge(0, 1).unwrap();
164 g.add_edge(0, 2).unwrap();
165 g.add_edge(0, 3).unwrap();
166 g.add_edge(0, 4).unwrap();
167 assert!(!satisfies_ore(&g).unwrap());
169 }
170
171 #[test]
172 fn directed_returns_false() {
173 let mut g = Graph::new(3, true).unwrap();
174 g.add_edge(0, 1).unwrap();
175 g.add_edge(1, 2).unwrap();
176 g.add_edge(2, 0).unwrap();
177 assert!(!satisfies_ore(&g).unwrap());
178 }
179
180 #[test]
181 fn k33_satisfies() {
182 let mut g = Graph::with_vertices(6);
184 for i in 0..3u32 {
185 for j in 3..6u32 {
186 g.add_edge(i, j).unwrap();
187 }
188 }
189 assert!(satisfies_ore(&g).unwrap());
190 }
191
192 #[test]
193 fn ore_but_not_dirac() {
194 let mut g = Graph::with_vertices(5);
207 g.add_edge(0, 1).unwrap();
208 g.add_edge(0, 2).unwrap();
209 g.add_edge(0, 3).unwrap();
210 g.add_edge(0, 4).unwrap();
211 g.add_edge(1, 2).unwrap();
212 g.add_edge(1, 3).unwrap();
213 g.add_edge(1, 4).unwrap();
214 g.add_edge(2, 3).unwrap();
215 assert!(satisfies_ore(&g).unwrap());
216 }
217
218 #[test]
219 fn edgeless_fails() {
220 let g = Graph::with_vertices(4);
221 assert!(!satisfies_ore(&g).unwrap());
222 }
223
224 #[test]
225 fn p3_fails() {
226 let mut g = Graph::with_vertices(3);
228 g.add_edge(0, 1).unwrap();
229 g.add_edge(1, 2).unwrap();
230 assert!(!satisfies_ore(&g).unwrap());
231 }
232}