networkit_rs/
component.rs

1use std::collections::BTreeMap;
2
3use cxx::UniquePtr;
4use miette::IntoDiagnostic;
5
6use crate::{
7    base::{Algorithm, DynAlgorithm},
8    bridge::{self, *},
9};
10
11pub trait ComponentDecomposition {
12    fn number_of_components(&self) -> u64;
13    fn component_of_node(&self, u: u64) -> u64;
14    fn get_partition(&self) -> crate::Partition;
15    fn get_component_sizes(&self) -> BTreeMap<u64, u64>;
16    fn get_components(&self) -> Vec<Vec<u64>>;
17}
18
19pub struct BiconnectedComponents {
20    inner: UniquePtr<bridge::BiconnectedComponents>,
21}
22
23impl BiconnectedComponents {
24    pub fn new(g: &crate::Graph) -> Self {
25        Self {
26            inner: NewBiconnectedComponents(g),
27        }
28    }
29    pub fn number_of_components(&self) -> u64 {
30        self.inner.numberOfComponents()
31    }
32    pub fn get_component_sizes(&self) -> BTreeMap<u64, u64> {
33        let mut ks = vec![];
34        let mut vs = vec![];
35        BiconnectedComponentsGetComponentSizes(&self.inner, &mut ks, &mut vs);
36        ks.into_iter().zip(vs).collect()
37    }
38    pub fn get_components(&self) -> Vec<Vec<u64>> {
39        let mut ks = vec![];
40        let mut vs = vec![];
41        BiconnectedComponentsGetComponents(&self.inner, &mut ks, &mut vs);
42        if ks.is_empty() {
43            vec![]
44        } else {
45            let l = ks.last().unwrap();
46            let mut ret = vec![vec![]; *l as usize + 1];
47            for (idx, v) in ks.into_iter().zip(vs) {
48                ret[idx as usize].push(v);
49            }
50            ret
51        }
52    }
53    pub fn get_component_of_node(&self, u: u64) -> Vec<u64> {
54        let mut vs = vec![];
55        BiconnectedComponentsGetComponentOfNode(&self.inner, u, &mut vs);
56        vs
57    }
58}
59
60impl Algorithm for BiconnectedComponents {
61    fn run(&mut self) -> miette::Result<()> {
62        self.inner.pin_mut().run().into_diagnostic()
63    }
64
65    fn has_finished(&self) -> bool {
66        self.inner.hasFinished()
67    }
68}
69
70pub struct ConnectedComponents {
71    inner: UniquePtr<bridge::ConnectedComponents>,
72}
73
74impl ConnectedComponents {
75    pub fn new(g: &crate::Graph) -> Self {
76        Self {
77            inner: NewConnectedComponents(g),
78        }
79    }
80
81    pub fn extract_largest_connected_component(
82        g: &crate::Graph,
83        compact_graph: bool,
84    ) -> crate::Graph {
85        ConnectedComponentsExtractLargestConnectedComponent(g, compact_graph).into()
86    }
87}
88
89impl Algorithm for ConnectedComponents {
90    fn run(&mut self) -> miette::Result<()> {
91        self.inner.pin_mut().run().into_diagnostic()
92    }
93
94    fn has_finished(&self) -> bool {
95        self.inner.hasFinished()
96    }
97}
98
99impl ComponentDecomposition for ConnectedComponents {
100    fn number_of_components(&self) -> u64 {
101        self.inner.numberOfComponents()
102    }
103    fn get_component_sizes(&self) -> BTreeMap<u64, u64> {
104        let mut ks = vec![];
105        let mut vs = vec![];
106        ConnectedComponentsGetComponentSizes(&self.inner, &mut ks, &mut vs);
107        ks.into_iter().zip(vs).collect()
108    }
109    fn get_components(&self) -> Vec<Vec<u64>> {
110        let mut ks = vec![];
111        let mut vs = vec![];
112        ConnectedComponentsGetComponents(&self.inner, &mut ks, &mut vs);
113        if ks.is_empty() {
114            vec![]
115        } else {
116            let l = ks.last().unwrap();
117            let mut ret = vec![vec![]; *l as usize + 1];
118            for (idx, v) in ks.into_iter().zip(vs) {
119                ret[idx as usize].push(v);
120            }
121            ret
122        }
123    }
124    fn component_of_node(&self, u: u64) -> u64 {
125        self.inner.componentOfNode(u)
126    }
127
128    fn get_partition(&self) -> crate::Partition {
129        ConnectedComponentsGetPartition(&self.inner).into()
130    }
131}
132
133pub struct DynConnectedComponents {
134    inner: UniquePtr<bridge::DynConnectedComponents>,
135}
136
137impl DynConnectedComponents {
138    pub fn new(g: &crate::Graph) -> Self {
139        Self {
140            inner: NewDynConnectedComponents(g),
141        }
142    }
143}
144
145impl Algorithm for DynConnectedComponents {
146    fn run(&mut self) -> miette::Result<()> {
147        self.inner.pin_mut().run().into_diagnostic()
148    }
149
150    fn has_finished(&self) -> bool {
151        self.inner.hasFinished()
152    }
153}
154
155impl ComponentDecomposition for DynConnectedComponents {
156    fn number_of_components(&self) -> u64 {
157        self.inner.numberOfComponents()
158    }
159    fn get_component_sizes(&self) -> BTreeMap<u64, u64> {
160        let mut ks = vec![];
161        let mut vs = vec![];
162        DynConnectedComponentsGetComponentSizes(&self.inner, &mut ks, &mut vs);
163        ks.into_iter().zip(vs).collect()
164    }
165    fn get_components(&self) -> Vec<Vec<u64>> {
166        let mut ks = vec![];
167        let mut vs = vec![];
168        DynConnectedComponentsGetComponents(&self.inner, &mut ks, &mut vs);
169        if ks.is_empty() {
170            vec![]
171        } else {
172            let l = ks.last().unwrap();
173            let mut ret = vec![vec![]; *l as usize + 1];
174            for (idx, v) in ks.into_iter().zip(vs) {
175                ret[idx as usize].push(v);
176            }
177            ret
178        }
179    }
180    fn component_of_node(&self, u: u64) -> u64 {
181        self.inner.componentOfNode(u)
182    }
183
184    fn get_partition(&self) -> crate::Partition {
185        DynConnectedComponentsGetPartition(&self.inner).into()
186    }
187}
188
189impl DynAlgorithm for DynConnectedComponents {
190    fn update(&mut self, e: crate::base::GraphEvent) {
191        DynConnectedComponentsUpdate(self.inner.pin_mut(), e.kind as u8, e.u, e.v, e.ew)
192    }
193
194    fn update_batch(&mut self, es: &[crate::base::GraphEvent]) {
195        let mut kinds = Vec::with_capacity(es.len());
196        let mut us = Vec::with_capacity(es.len());
197        let mut vs = Vec::with_capacity(es.len());
198        let mut ews = Vec::with_capacity(es.len());
199        for ev in es {
200            kinds.push(ev.kind as u8);
201            us.push(ev.u);
202            vs.push(ev.v);
203            ews.push(ev.ew);
204        }
205        DynConnectedComponentsUpdateBatch(self.inner.pin_mut(), &kinds, &us, &vs, &ews);
206    }
207}
208
209pub struct DynWeaklyConnectedComponents {
210    inner: UniquePtr<bridge::DynWeaklyConnectedComponents>,
211}
212
213impl DynWeaklyConnectedComponents {
214    pub fn new(g: &crate::Graph) -> Self {
215        Self {
216            inner: NewDynWeaklyConnectedComponents(g),
217        }
218    }
219}
220
221impl Algorithm for DynWeaklyConnectedComponents {
222    fn run(&mut self) -> miette::Result<()> {
223        self.inner.pin_mut().run().into_diagnostic()
224    }
225
226    fn has_finished(&self) -> bool {
227        self.inner.hasFinished()
228    }
229}
230
231impl ComponentDecomposition for DynWeaklyConnectedComponents {
232    fn number_of_components(&self) -> u64 {
233        self.inner.numberOfComponents()
234    }
235    fn get_component_sizes(&self) -> BTreeMap<u64, u64> {
236        let mut ks = vec![];
237        let mut vs = vec![];
238        DynWeaklyConnectedComponentsGetComponentSizes(&self.inner, &mut ks, &mut vs);
239        ks.into_iter().zip(vs).collect()
240    }
241    fn get_components(&self) -> Vec<Vec<u64>> {
242        let mut ks = vec![];
243        let mut vs = vec![];
244        DynWeaklyConnectedComponentsGetComponents(&self.inner, &mut ks, &mut vs);
245        if ks.is_empty() {
246            vec![]
247        } else {
248            let l = ks.last().unwrap();
249            let mut ret = vec![vec![]; *l as usize + 1];
250            for (idx, v) in ks.into_iter().zip(vs) {
251                ret[idx as usize].push(v);
252            }
253            ret
254        }
255    }
256    fn component_of_node(&self, u: u64) -> u64 {
257        self.inner.componentOfNode(u)
258    }
259
260    fn get_partition(&self) -> crate::Partition {
261        DynWeaklyConnectedComponentsGetPartition(&self.inner).into()
262    }
263}
264
265impl DynAlgorithm for DynWeaklyConnectedComponents {
266    fn update(&mut self, e: crate::base::GraphEvent) {
267        DynWeaklyConnectedComponentsUpdate(self.inner.pin_mut(), e.kind as u8, e.u, e.v, e.ew)
268    }
269
270    fn update_batch(&mut self, es: &[crate::base::GraphEvent]) {
271        let mut kinds = Vec::with_capacity(es.len());
272        let mut us = Vec::with_capacity(es.len());
273        let mut vs = Vec::with_capacity(es.len());
274        let mut ews = Vec::with_capacity(es.len());
275        for ev in es {
276            kinds.push(ev.kind as u8);
277            us.push(ev.u);
278            vs.push(ev.v);
279            ews.push(ev.ew);
280        }
281        DynWeaklyConnectedComponentsUpdateBatch(self.inner.pin_mut(), &kinds, &us, &vs, &ews);
282    }
283}
284
285pub struct ParallelConnectedComponents {
286    inner: UniquePtr<bridge::ParallelConnectedComponents>,
287}
288
289impl ParallelConnectedComponents {
290    pub fn new(g: &crate::Graph, coarsening: bool) -> Self {
291        Self {
292            inner: NewParallelConnectedComponents(g, coarsening),
293        }
294    }
295}
296
297impl Algorithm for ParallelConnectedComponents {
298    fn run(&mut self) -> miette::Result<()> {
299        self.inner.pin_mut().run().into_diagnostic()
300    }
301
302    fn has_finished(&self) -> bool {
303        self.inner.hasFinished()
304    }
305}
306
307impl ComponentDecomposition for ParallelConnectedComponents {
308    fn number_of_components(&self) -> u64 {
309        self.inner.numberOfComponents()
310    }
311    fn get_component_sizes(&self) -> BTreeMap<u64, u64> {
312        let mut ks = vec![];
313        let mut vs = vec![];
314        ParallelConnectedComponentsGetComponentSizes(&self.inner, &mut ks, &mut vs);
315        ks.into_iter().zip(vs).collect()
316    }
317    fn get_components(&self) -> Vec<Vec<u64>> {
318        let mut ks = vec![];
319        let mut vs = vec![];
320        ParallelConnectedComponentsGetComponents(&self.inner, &mut ks, &mut vs);
321        if ks.is_empty() {
322            vec![]
323        } else {
324            let l = ks.last().unwrap();
325            let mut ret = vec![vec![]; *l as usize + 1];
326            for (idx, v) in ks.into_iter().zip(vs) {
327                ret[idx as usize].push(v);
328            }
329            ret
330        }
331    }
332    fn component_of_node(&self, u: u64) -> u64 {
333        self.inner.componentOfNode(u)
334    }
335
336    fn get_partition(&self) -> crate::Partition {
337        ParallelConnectedComponentsGetPartition(&self.inner).into()
338    }
339}
340
341pub struct StronglyConnectedComponents {
342    inner: UniquePtr<bridge::StronglyConnectedComponents>,
343}
344
345impl StronglyConnectedComponents {
346    pub fn new(g: &crate::Graph) -> Self {
347        Self {
348            inner: NewStronglyConnectedComponents(g),
349        }
350    }
351}
352
353impl Algorithm for StronglyConnectedComponents {
354    fn run(&mut self) -> miette::Result<()> {
355        self.inner.pin_mut().run().into_diagnostic()
356    }
357
358    fn has_finished(&self) -> bool {
359        self.inner.hasFinished()
360    }
361}
362
363impl ComponentDecomposition for StronglyConnectedComponents {
364    fn number_of_components(&self) -> u64 {
365        self.inner.numberOfComponents()
366    }
367    fn get_component_sizes(&self) -> BTreeMap<u64, u64> {
368        let mut ks = vec![];
369        let mut vs = vec![];
370        StronglyConnectedComponentsGetComponentSizes(&self.inner, &mut ks, &mut vs);
371        ks.into_iter().zip(vs).collect()
372    }
373    fn get_components(&self) -> Vec<Vec<u64>> {
374        let mut ks = vec![];
375        let mut vs = vec![];
376        StronglyConnectedComponentsGetComponents(&self.inner, &mut ks, &mut vs);
377        if ks.is_empty() {
378            vec![]
379        } else {
380            let l = ks.last().unwrap();
381            let mut ret = vec![vec![]; *l as usize + 1];
382            for (idx, v) in ks.into_iter().zip(vs) {
383                ret[idx as usize].push(v);
384            }
385            ret
386        }
387    }
388    fn component_of_node(&self, u: u64) -> u64 {
389        self.inner.componentOfNode(u)
390    }
391
392    fn get_partition(&self) -> crate::Partition {
393        StronglyConnectedComponentsGetPartition(&self.inner).into()
394    }
395}
396
397pub struct WeaklyConnectedComponents {
398    inner: UniquePtr<bridge::WeaklyConnectedComponents>,
399}
400
401impl WeaklyConnectedComponents {
402    pub fn new(g: &crate::Graph) -> Self {
403        Self {
404            inner: NewWeaklyConnectedComponents(g),
405        }
406    }
407}
408
409impl Algorithm for WeaklyConnectedComponents {
410    fn run(&mut self) -> miette::Result<()> {
411        self.inner.pin_mut().run().into_diagnostic()
412    }
413
414    fn has_finished(&self) -> bool {
415        self.inner.hasFinished()
416    }
417}
418
419impl ComponentDecomposition for WeaklyConnectedComponents {
420    fn number_of_components(&self) -> u64 {
421        self.inner.numberOfComponents()
422    }
423    fn get_component_sizes(&self) -> BTreeMap<u64, u64> {
424        let mut ks = vec![];
425        let mut vs = vec![];
426        WeaklyConnectedComponentsGetComponentSizes(&self.inner, &mut ks, &mut vs);
427        ks.into_iter().zip(vs).collect()
428    }
429    fn get_components(&self) -> Vec<Vec<u64>> {
430        let mut ks = vec![];
431        let mut vs = vec![];
432        WeaklyConnectedComponentsGetComponents(&self.inner, &mut ks, &mut vs);
433        if ks.is_empty() {
434            vec![]
435        } else {
436            let l = ks.last().unwrap();
437            let mut ret = vec![vec![]; *l as usize + 1];
438            for (idx, v) in ks.into_iter().zip(vs) {
439                ret[idx as usize].push(v);
440            }
441            ret
442        }
443    }
444    fn component_of_node(&self, u: u64) -> u64 {
445        self.inner.componentOfNode(u)
446    }
447
448    fn get_partition(&self) -> crate::Partition {
449        WeaklyConnectedComponentsGetPartition(&self.inner).into()
450    }
451}