rust_igraph/algorithms/properties/
is_k_degenerate.rs1use crate::algorithms::properties::coreness::coreness;
11use crate::core::{Graph, IgraphResult};
12
13pub fn is_k_degenerate(graph: &Graph, k: u32) -> IgraphResult<bool> {
45 let n = graph.vcount();
46 if n == 0 {
47 return Ok(true);
48 }
49
50 let cores = coreness(graph)?;
51 let max_core = cores.iter().copied().max().unwrap_or(0);
52 Ok(max_core <= k)
53}
54
55pub fn degeneracy(graph: &Graph) -> IgraphResult<u32> {
74 let n = graph.vcount();
75 if n == 0 {
76 return Ok(0);
77 }
78
79 let cores = coreness(graph)?;
80 Ok(cores.iter().copied().max().unwrap_or(0))
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
88 fn empty_graph() {
89 let g = Graph::with_vertices(0);
90 assert!(is_k_degenerate(&g, 0).unwrap());
91 assert_eq!(degeneracy(&g).unwrap(), 0);
92 }
93
94 #[test]
95 fn single_vertex() {
96 let g = Graph::with_vertices(1);
97 assert!(is_k_degenerate(&g, 0).unwrap());
98 assert_eq!(degeneracy(&g).unwrap(), 0);
99 }
100
101 #[test]
102 fn single_edge() {
103 let mut g = Graph::with_vertices(2);
104 g.add_edge(0, 1).unwrap();
105 assert!(!is_k_degenerate(&g, 0).unwrap());
106 assert!(is_k_degenerate(&g, 1).unwrap());
107 assert_eq!(degeneracy(&g).unwrap(), 1);
108 }
109
110 #[test]
111 fn triangle() {
112 let mut g = Graph::with_vertices(3);
113 g.add_edge(0, 1).unwrap();
114 g.add_edge(1, 2).unwrap();
115 g.add_edge(2, 0).unwrap();
116 assert!(!is_k_degenerate(&g, 1).unwrap());
117 assert!(is_k_degenerate(&g, 2).unwrap());
118 assert_eq!(degeneracy(&g).unwrap(), 2);
119 }
120
121 #[test]
122 fn tree() {
123 let mut g = Graph::with_vertices(5);
124 g.add_edge(0, 1).unwrap();
125 g.add_edge(1, 2).unwrap();
126 g.add_edge(1, 3).unwrap();
127 g.add_edge(3, 4).unwrap();
128 assert!(is_k_degenerate(&g, 1).unwrap());
129 assert!(!is_k_degenerate(&g, 0).unwrap());
130 assert_eq!(degeneracy(&g).unwrap(), 1);
131 }
132
133 #[test]
134 fn complete_k4() {
135 let mut g = Graph::with_vertices(4);
136 for i in 0..4u32 {
137 for j in (i + 1)..4 {
138 g.add_edge(i, j).unwrap();
139 }
140 }
141 assert!(!is_k_degenerate(&g, 2).unwrap());
142 assert!(is_k_degenerate(&g, 3).unwrap());
143 assert_eq!(degeneracy(&g).unwrap(), 3);
144 }
145
146 #[test]
147 fn complete_k5() {
148 let mut g = Graph::with_vertices(5);
149 for i in 0..5u32 {
150 for j in (i + 1)..5 {
151 g.add_edge(i, j).unwrap();
152 }
153 }
154 assert_eq!(degeneracy(&g).unwrap(), 4);
155 }
156
157 #[test]
158 fn edgeless() {
159 let g = Graph::with_vertices(5);
160 assert!(is_k_degenerate(&g, 0).unwrap());
161 assert_eq!(degeneracy(&g).unwrap(), 0);
162 }
163
164 #[test]
165 fn star() {
166 let mut g = Graph::with_vertices(5);
167 g.add_edge(0, 1).unwrap();
168 g.add_edge(0, 2).unwrap();
169 g.add_edge(0, 3).unwrap();
170 g.add_edge(0, 4).unwrap();
171 assert!(is_k_degenerate(&g, 1).unwrap());
172 assert_eq!(degeneracy(&g).unwrap(), 1);
173 }
174
175 #[test]
176 fn c4() {
177 let mut g = Graph::with_vertices(4);
179 g.add_edge(0, 1).unwrap();
180 g.add_edge(1, 2).unwrap();
181 g.add_edge(2, 3).unwrap();
182 g.add_edge(3, 0).unwrap();
183 assert!(is_k_degenerate(&g, 2).unwrap());
184 assert!(!is_k_degenerate(&g, 1).unwrap());
185 assert_eq!(degeneracy(&g).unwrap(), 2);
186 }
187
188 #[test]
189 fn directed_treated_as_undirected() {
190 let mut g = Graph::new(3, true).unwrap();
191 g.add_edge(0, 1).unwrap();
192 g.add_edge(1, 2).unwrap();
193 g.add_edge(2, 0).unwrap();
194 assert!(is_k_degenerate(&g, 2).unwrap());
195 assert_eq!(degeneracy(&g).unwrap(), 2);
196 }
197
198 #[test]
199 fn large_k_always_true() {
200 let mut g = Graph::with_vertices(3);
201 g.add_edge(0, 1).unwrap();
202 assert!(is_k_degenerate(&g, 100).unwrap());
203 }
204
205 #[test]
206 fn path() {
207 let mut g = Graph::with_vertices(5);
208 g.add_edge(0, 1).unwrap();
209 g.add_edge(1, 2).unwrap();
210 g.add_edge(2, 3).unwrap();
211 g.add_edge(3, 4).unwrap();
212 assert!(is_k_degenerate(&g, 1).unwrap());
213 assert_eq!(degeneracy(&g).unwrap(), 1);
214 }
215}