networkit_rs/
link_prediction.rs

1use cxx::UniquePtr;
2
3use crate::{
4    bridge::{self, *},
5    tools::NodeIter,
6};
7
8pub trait LinkPredictor {
9    fn set_graph(&mut self, g: &crate::Graph);
10    fn run(&mut self, u: u64, v: u64) -> f64;
11    fn run_on(&mut self, pairs: &[(u64, u64)]) -> Vec<((u64, u64), f64)>;
12    fn run_all(&mut self) -> Vec<((u64, u64), f64)>;
13}
14
15pub trait EvaluationMetric {
16    fn set_test_graph(&mut self, g: &crate::Graph);
17    fn get_curve(
18        &mut self,
19        prediction: &[((u64, u64), f64)],
20        num_threshold: u64,
21    ) -> Vec<(f64, f64)>;
22    fn get_area_under_curve(&self, curve: &[(f64, f64)]) -> f64;
23    fn get_last_area_under_curve(&self) -> f64;
24}
25
26pub struct AdamicAdarIndex {
27    inner: UniquePtr<bridge::AdamicAdarIndex>,
28}
29
30impl AdamicAdarIndex {
31    pub fn new(g: &crate::Graph) -> Self {
32        Self {
33            inner: NewAdamicAdarIndex(g),
34        }
35    }
36}
37
38impl LinkPredictor for AdamicAdarIndex {
39    fn set_graph(&mut self, g: &crate::Graph) {
40        self.inner.pin_mut().setGraph(g)
41    }
42
43    fn run(&mut self, u: u64, v: u64) -> f64 {
44        self.inner.pin_mut().run(u, v)
45    }
46
47    fn run_on(&mut self, pairs: &[(u64, u64)]) -> Vec<((u64, u64), f64)> {
48        let mut src = Vec::with_capacity(pairs.len());
49        let mut dst = Vec::with_capacity(pairs.len());
50        for (s, d) in pairs {
51            src.push(*s);
52            dst.push(*d);
53        }
54        let mut ks = vec![];
55        let mut vs = vec![];
56        let mut ws = vec![];
57        AdamicAdarIndexRunOn(self.inner.pin_mut(), &src, &dst, &mut ks, &mut vs, &mut ws);
58        ks.into_iter().zip(vs).zip(ws).collect()
59    }
60
61    fn run_all(&mut self) -> Vec<((u64, u64), f64)> {
62        let mut ks = vec![];
63        let mut vs = vec![];
64        let mut ws = vec![];
65        AdamicAdarIndexRunAll(self.inner.pin_mut(), &mut ks, &mut vs, &mut ws);
66        ks.into_iter().zip(vs).zip(ws).collect()
67    }
68}
69
70pub struct AdjustedRandIndex {
71    inner: UniquePtr<bridge::AdjustedRandIndex>,
72}
73
74impl AdjustedRandIndex {
75    pub fn new(g: &crate::Graph) -> Self {
76        Self {
77            inner: NewAdjustedRandIndex(g),
78        }
79    }
80}
81
82impl LinkPredictor for AdjustedRandIndex {
83    fn set_graph(&mut self, g: &crate::Graph) {
84        self.inner.pin_mut().setGraph(g)
85    }
86
87    fn run(&mut self, u: u64, v: u64) -> f64 {
88        self.inner.pin_mut().run(u, v)
89    }
90
91    fn run_on(&mut self, pairs: &[(u64, u64)]) -> Vec<((u64, u64), f64)> {
92        let mut src = Vec::with_capacity(pairs.len());
93        let mut dst = Vec::with_capacity(pairs.len());
94        for (s, d) in pairs {
95            src.push(*s);
96            dst.push(*d);
97        }
98        let mut ks = vec![];
99        let mut vs = vec![];
100        let mut ws = vec![];
101        AdjustedRandIndexRunOn(self.inner.pin_mut(), &src, &dst, &mut ks, &mut vs, &mut ws);
102        ks.into_iter().zip(vs).zip(ws).collect()
103    }
104
105    fn run_all(&mut self) -> Vec<((u64, u64), f64)> {
106        let mut ks = vec![];
107        let mut vs = vec![];
108        let mut ws = vec![];
109        AdjustedRandIndexRunAll(self.inner.pin_mut(), &mut ks, &mut vs, &mut ws);
110        ks.into_iter().zip(vs).zip(ws).collect()
111    }
112}
113
114pub struct AlgebraicDistanceIndex {
115    inner: UniquePtr<bridge::AlgebraicDistanceIndex>,
116}
117
118impl AlgebraicDistanceIndex {
119    pub fn new(
120        g: &crate::Graph,
121        num_systems: u64,
122        num_iterations: u64,
123        omega: f64,
124        norm: u64,
125    ) -> Self {
126        Self {
127            inner: NewAlgebraicDistanceIndex(g, num_systems, num_iterations, omega, norm),
128        }
129    }
130    pub fn preprocess(&mut self) {
131        self.inner.pin_mut().preprocess()
132    }
133}
134
135impl LinkPredictor for AlgebraicDistanceIndex {
136    fn set_graph(&mut self, g: &crate::Graph) {
137        self.inner.pin_mut().setGraph(g)
138    }
139
140    fn run(&mut self, u: u64, v: u64) -> f64 {
141        self.inner.pin_mut().run(u, v)
142    }
143
144    fn run_on(&mut self, pairs: &[(u64, u64)]) -> Vec<((u64, u64), f64)> {
145        let mut src = Vec::with_capacity(pairs.len());
146        let mut dst = Vec::with_capacity(pairs.len());
147        for (s, d) in pairs {
148            src.push(*s);
149            dst.push(*d);
150        }
151        let mut ks = vec![];
152        let mut vs = vec![];
153        let mut ws = vec![];
154        AlgebraicDistanceIndexRunOn(self.inner.pin_mut(), &src, &dst, &mut ks, &mut vs, &mut ws);
155        ks.into_iter().zip(vs).zip(ws).collect()
156    }
157
158    fn run_all(&mut self) -> Vec<((u64, u64), f64)> {
159        let mut ks = vec![];
160        let mut vs = vec![];
161        let mut ws = vec![];
162        AlgebraicDistanceIndexRunAll(self.inner.pin_mut(), &mut ks, &mut vs, &mut ws);
163        ks.into_iter().zip(vs).zip(ws).collect()
164    }
165}
166
167pub struct CommonNeighborsIndex {
168    inner: UniquePtr<bridge::CommonNeighborsIndex>,
169}
170
171impl CommonNeighborsIndex {
172    pub fn new(g: &crate::Graph) -> Self {
173        Self {
174            inner: NewCommonNeighborsIndex(g),
175        }
176    }
177}
178
179impl LinkPredictor for CommonNeighborsIndex {
180    fn set_graph(&mut self, g: &crate::Graph) {
181        self.inner.pin_mut().setGraph(g)
182    }
183
184    fn run(&mut self, u: u64, v: u64) -> f64 {
185        self.inner.pin_mut().run(u, v)
186    }
187
188    fn run_on(&mut self, pairs: &[(u64, u64)]) -> Vec<((u64, u64), f64)> {
189        let mut src = Vec::with_capacity(pairs.len());
190        let mut dst = Vec::with_capacity(pairs.len());
191        for (s, d) in pairs {
192            src.push(*s);
193            dst.push(*d);
194        }
195        let mut ks = vec![];
196        let mut vs = vec![];
197        let mut ws = vec![];
198        CommonNeighborsIndexRunOn(self.inner.pin_mut(), &src, &dst, &mut ks, &mut vs, &mut ws);
199        ks.into_iter().zip(vs).zip(ws).collect()
200    }
201
202    fn run_all(&mut self) -> Vec<((u64, u64), f64)> {
203        let mut ks = vec![];
204        let mut vs = vec![];
205        let mut ws = vec![];
206        CommonNeighborsIndexRunAll(self.inner.pin_mut(), &mut ks, &mut vs, &mut ws);
207        ks.into_iter().zip(vs).zip(ws).collect()
208    }
209}
210
211pub struct ROCMetric {
212    inner: UniquePtr<bridge::ROCMetric>,
213}
214
215impl ROCMetric {
216    pub fn new(g: &crate::Graph) -> Self {
217        Self {
218            inner: NewROCMetric(g),
219        }
220    }
221}
222
223impl EvaluationMetric for ROCMetric {
224    fn set_test_graph(&mut self, g: &crate::Graph) {
225        self.inner.pin_mut().setTestGraph(g)
226    }
227
228    fn get_curve(
229        &mut self,
230        prediction: &[((u64, u64), f64)],
231        num_threshold: u64,
232    ) -> Vec<(f64, f64)> {
233        let mut us = Vec::with_capacity(prediction.len());
234        let mut vs = Vec::with_capacity(prediction.len());
235        let mut ws = Vec::with_capacity(prediction.len());
236        for ((u, v), w) in prediction {
237            us.push(*u);
238            vs.push(*v);
239            ws.push(*w);
240        }
241        let mut xs = vec![];
242        let mut ys = vec![];
243        ROCMetricGetCurve(
244            self.inner.pin_mut(),
245            &us,
246            &vs,
247            &ws,
248            num_threshold,
249            &mut xs,
250            &mut ys,
251        );
252        xs.into_iter().zip(ys).collect()
253    }
254
255    fn get_area_under_curve(&self, curve: &[(f64, f64)]) -> f64 {
256        let mut xs = Vec::with_capacity(curve.len());
257        let mut ys = Vec::with_capacity(curve.len());
258        for (x, y) in curve {
259            xs.push(*x);
260            ys.push(*y);
261        }
262        ROCMetricGetAreaUnderCurve(&self.inner, &xs, &ys)
263    }
264
265    fn get_last_area_under_curve(&self) -> f64 {
266        self.inner.getAreaUnderCurve()
267    }
268}
269
270pub struct PrecisionRecallMetric {
271    inner: UniquePtr<bridge::PrecisionRecallMetric>,
272}
273
274impl PrecisionRecallMetric {
275    pub fn new(g: &crate::Graph) -> Self {
276        Self {
277            inner: NewPrecisionRecallMetric(g),
278        }
279    }
280}
281
282impl EvaluationMetric for PrecisionRecallMetric {
283    fn set_test_graph(&mut self, g: &crate::Graph) {
284        self.inner.pin_mut().setTestGraph(g)
285    }
286
287    fn get_curve(
288        &mut self,
289        prediction: &[((u64, u64), f64)],
290        num_threshold: u64,
291    ) -> Vec<(f64, f64)> {
292        let mut us = Vec::with_capacity(prediction.len());
293        let mut vs = Vec::with_capacity(prediction.len());
294        let mut ws = Vec::with_capacity(prediction.len());
295        for ((u, v), w) in prediction {
296            us.push(*u);
297            vs.push(*v);
298            ws.push(*w);
299        }
300        let mut xs = vec![];
301        let mut ys = vec![];
302        PrecisionRecallMetricGetCurve(
303            self.inner.pin_mut(),
304            &us,
305            &vs,
306            &ws,
307            num_threshold,
308            &mut xs,
309            &mut ys,
310        );
311        xs.into_iter().zip(ys).collect()
312    }
313
314    fn get_area_under_curve(&self, curve: &[(f64, f64)]) -> f64 {
315        let mut xs = Vec::with_capacity(curve.len());
316        let mut ys = Vec::with_capacity(curve.len());
317        for (x, y) in curve {
318            xs.push(*x);
319            ys.push(*y);
320        }
321        PrecisionRecallMetricGetAreaUnderCurve(&self.inner, &xs, &ys)
322    }
323
324    fn get_last_area_under_curve(&self) -> f64 {
325        self.inner.getAreaUnderCurve()
326    }
327}
328
329pub struct JaccardIndex {
330    inner: UniquePtr<bridge::JaccardIndex>,
331}
332
333impl JaccardIndex {
334    pub fn new(g: &crate::Graph) -> Self {
335        Self {
336            inner: NewJaccardIndex(g),
337        }
338    }
339}
340
341impl LinkPredictor for JaccardIndex {
342    fn set_graph(&mut self, g: &crate::Graph) {
343        self.inner.pin_mut().setGraph(g)
344    }
345
346    fn run(&mut self, u: u64, v: u64) -> f64 {
347        self.inner.pin_mut().run(u, v)
348    }
349
350    fn run_on(&mut self, pairs: &[(u64, u64)]) -> Vec<((u64, u64), f64)> {
351        let mut src = Vec::with_capacity(pairs.len());
352        let mut dst = Vec::with_capacity(pairs.len());
353        for (s, d) in pairs {
354            src.push(*s);
355            dst.push(*d);
356        }
357        let mut ks = vec![];
358        let mut vs = vec![];
359        let mut ws = vec![];
360        JaccardIndexRunOn(self.inner.pin_mut(), &src, &dst, &mut ks, &mut vs, &mut ws);
361        ks.into_iter().zip(vs).zip(ws).collect()
362    }
363
364    fn run_all(&mut self) -> Vec<((u64, u64), f64)> {
365        let mut ks = vec![];
366        let mut vs = vec![];
367        let mut ws = vec![];
368        JaccardIndexRunAll(self.inner.pin_mut(), &mut ks, &mut vs, &mut ws);
369        ks.into_iter().zip(vs).zip(ws).collect()
370    }
371}
372
373pub struct KatzIndex {
374    inner: UniquePtr<bridge::KatzIndex>,
375}
376
377impl KatzIndex {
378    pub fn new(g: &crate::Graph, max_path_length: Option<u64>, damping_value: Option<f64>) -> Self {
379        Self {
380            inner: NewKatzIndex(
381                g,
382                max_path_length.unwrap_or(5),
383                damping_value.unwrap_or(0.005),
384            ),
385        }
386    }
387}
388
389impl LinkPredictor for KatzIndex {
390    fn set_graph(&mut self, g: &crate::Graph) {
391        self.inner.pin_mut().setGraph(g)
392    }
393
394    fn run(&mut self, u: u64, v: u64) -> f64 {
395        self.inner.pin_mut().run(u, v)
396    }
397
398    fn run_on(&mut self, pairs: &[(u64, u64)]) -> Vec<((u64, u64), f64)> {
399        let mut src = Vec::with_capacity(pairs.len());
400        let mut dst = Vec::with_capacity(pairs.len());
401        for (s, d) in pairs {
402            src.push(*s);
403            dst.push(*d);
404        }
405        let mut ks = vec![];
406        let mut vs = vec![];
407        let mut ws = vec![];
408        KatzIndexRunOn(self.inner.pin_mut(), &src, &dst, &mut ks, &mut vs, &mut ws);
409        ks.into_iter().zip(vs).zip(ws).collect()
410    }
411
412    fn run_all(&mut self) -> Vec<((u64, u64), f64)> {
413        let mut ks = vec![];
414        let mut vs = vec![];
415        let mut ws = vec![];
416        KatzIndexRunAll(self.inner.pin_mut(), &mut ks, &mut vs, &mut ws);
417        ks.into_iter().zip(vs).zip(ws).collect()
418    }
419}
420
421pub struct LinkThresholder;
422
423impl LinkThresholder {
424    pub fn by_count(prediction: &[((u64, u64), f64)], num_links: u64) -> Vec<(u64, u64)> {
425        let mut us = Vec::with_capacity(prediction.len());
426        let mut vs = Vec::with_capacity(prediction.len());
427        let mut ws = Vec::with_capacity(prediction.len());
428        for ((u, v), w) in prediction {
429            us.push(*u);
430            vs.push(*v);
431            ws.push(*w);
432        }
433        let mut src = vec![];
434        let mut dst = vec![];
435        LinkThresholderByCount(&us, &vs, &ws, num_links, &mut src, &mut dst);
436        src.into_iter().zip(dst).collect()
437    }
438    pub fn by_percentage(
439        prediction: &[((u64, u64), f64)],
440        percentage_links: f64,
441    ) -> Vec<(u64, u64)> {
442        let mut us = Vec::with_capacity(prediction.len());
443        let mut vs = Vec::with_capacity(prediction.len());
444        let mut ws = Vec::with_capacity(prediction.len());
445        for ((u, v), w) in prediction {
446            us.push(*u);
447            vs.push(*v);
448            ws.push(*w);
449        }
450        let mut src = vec![];
451        let mut dst = vec![];
452        LinkThresholderByPercentage(&us, &vs, &ws, percentage_links, &mut src, &mut dst);
453        src.into_iter().zip(dst).collect()
454    }
455    pub fn by_score(prediction: &[((u64, u64), f64)], min_score: f64) -> Vec<(u64, u64)> {
456        let mut us = Vec::with_capacity(prediction.len());
457        let mut vs = Vec::with_capacity(prediction.len());
458        let mut ws = Vec::with_capacity(prediction.len());
459        for ((u, v), w) in prediction {
460            us.push(*u);
461            vs.push(*v);
462            ws.push(*w);
463        }
464        let mut src = vec![];
465        let mut dst = vec![];
466        LinkThresholderByScore(&us, &vs, &ws, min_score, &mut src, &mut dst);
467        src.into_iter().zip(dst).collect()
468    }
469}
470
471pub struct MissingLinksFinder {
472    inner: UniquePtr<bridge::MissingLinksFinder>,
473}
474
475impl MissingLinksFinder {
476    pub fn new(g: &crate::Graph) -> Self {
477        Self {
478            inner: NewMissingLinksFinder(g),
479        }
480    }
481    pub fn find_at_distance(&mut self, k: u64) -> impl Iterator<Item = (u64, u64)> {
482        let mut src = vec![];
483        let mut dst = vec![];
484        MissingLinksFinderFindAtDistance(self.inner.pin_mut(), k, &mut src, &mut dst);
485        src.into_iter().zip(dst)
486    }
487    pub fn find_from_node(&mut self, u: u64, k: u64) -> impl Iterator<Item = (u64, u64)> {
488        let mut src = vec![];
489        let mut dst = vec![];
490        MissingLinksFinderFindFromNode(self.inner.pin_mut(), u, k, &mut src, &mut dst);
491        src.into_iter().zip(dst)
492    }
493}
494
495pub struct NeighborhoodDistanceIndex {
496    inner: UniquePtr<bridge::NeighborhoodDistanceIndex>,
497}
498
499impl NeighborhoodDistanceIndex {
500    pub fn new(g: &crate::Graph) -> Self {
501        Self {
502            inner: NewNeighborhoodDistanceIndex(g),
503        }
504    }
505}
506
507impl LinkPredictor for NeighborhoodDistanceIndex {
508    fn set_graph(&mut self, g: &crate::Graph) {
509        self.inner.pin_mut().setGraph(g)
510    }
511
512    fn run(&mut self, u: u64, v: u64) -> f64 {
513        self.inner.pin_mut().run(u, v)
514    }
515
516    fn run_on(&mut self, pairs: &[(u64, u64)]) -> Vec<((u64, u64), f64)> {
517        let mut src = Vec::with_capacity(pairs.len());
518        let mut dst = Vec::with_capacity(pairs.len());
519        for (s, d) in pairs {
520            src.push(*s);
521            dst.push(*d);
522        }
523        let mut ks = vec![];
524        let mut vs = vec![];
525        let mut ws = vec![];
526        NeighborhoodDistanceIndexRunOn(self.inner.pin_mut(), &src, &dst, &mut ks, &mut vs, &mut ws);
527        ks.into_iter().zip(vs).zip(ws).collect()
528    }
529
530    fn run_all(&mut self) -> Vec<((u64, u64), f64)> {
531        let mut ks = vec![];
532        let mut vs = vec![];
533        let mut ws = vec![];
534        NeighborhoodDistanceIndexRunAll(self.inner.pin_mut(), &mut ks, &mut vs, &mut ws);
535        ks.into_iter().zip(vs).zip(ws).collect()
536    }
537}
538
539pub struct NeighbourhoodUtility;
540
541impl NeighbourhoodUtility {
542    pub fn get_neighbours_union(g: &crate::Graph, u: u64, v: u64) -> NodeIter {
543        NodeIter {
544            at: 0,
545            nodes: NeighborhoodUtilityGetNeighborsUnion(g, u, v),
546        }
547    }
548    pub fn get_common_neighbours(g: &crate::Graph, u: u64, v: u64) -> NodeIter {
549        NodeIter {
550            at: 0,
551            nodes: NeighborhoodUtilityGetCommonNeighbors(g, u, v),
552        }
553    }
554}
555
556pub struct NeighborsMeasureIndex {
557    inner: UniquePtr<bridge::NeighborsMeasureIndex>,
558}
559
560impl NeighborsMeasureIndex {
561    pub fn new(g: &crate::Graph) -> Self {
562        Self {
563            inner: NewNeighborsMeasureIndex(g),
564        }
565    }
566}
567
568impl LinkPredictor for NeighborsMeasureIndex {
569    fn set_graph(&mut self, g: &crate::Graph) {
570        self.inner.pin_mut().setGraph(g)
571    }
572
573    fn run(&mut self, u: u64, v: u64) -> f64 {
574        self.inner.pin_mut().run(u, v)
575    }
576
577    fn run_on(&mut self, pairs: &[(u64, u64)]) -> Vec<((u64, u64), f64)> {
578        let mut src = Vec::with_capacity(pairs.len());
579        let mut dst = Vec::with_capacity(pairs.len());
580        for (s, d) in pairs {
581            src.push(*s);
582            dst.push(*d);
583        }
584        let mut ks = vec![];
585        let mut vs = vec![];
586        let mut ws = vec![];
587        NeighborsMeasureIndexRunOn(self.inner.pin_mut(), &src, &dst, &mut ks, &mut vs, &mut ws);
588        ks.into_iter().zip(vs).zip(ws).collect()
589    }
590
591    fn run_all(&mut self) -> Vec<((u64, u64), f64)> {
592        let mut ks = vec![];
593        let mut vs = vec![];
594        let mut ws = vec![];
595        NeighborsMeasureIndexRunAll(self.inner.pin_mut(), &mut ks, &mut vs, &mut ws);
596        ks.into_iter().zip(vs).zip(ws).collect()
597    }
598}
599
600pub struct PreferentialAttachmentIndex {
601    inner: UniquePtr<bridge::PreferentialAttachmentIndex>,
602}
603
604impl PreferentialAttachmentIndex {
605    pub fn new(g: &crate::Graph) -> Self {
606        Self {
607            inner: NewPreferentialAttachmentIndex(g),
608        }
609    }
610}
611
612impl LinkPredictor for PreferentialAttachmentIndex {
613    fn set_graph(&mut self, g: &crate::Graph) {
614        self.inner.pin_mut().setGraph(g)
615    }
616
617    fn run(&mut self, u: u64, v: u64) -> f64 {
618        self.inner.pin_mut().run(u, v)
619    }
620
621    fn run_on(&mut self, pairs: &[(u64, u64)]) -> Vec<((u64, u64), f64)> {
622        let mut src = Vec::with_capacity(pairs.len());
623        let mut dst = Vec::with_capacity(pairs.len());
624        for (s, d) in pairs {
625            src.push(*s);
626            dst.push(*d);
627        }
628        let mut ks = vec![];
629        let mut vs = vec![];
630        let mut ws = vec![];
631        PreferentialAttachmentIndexRunOn(
632            self.inner.pin_mut(),
633            &src,
634            &dst,
635            &mut ks,
636            &mut vs,
637            &mut ws,
638        );
639        ks.into_iter().zip(vs).zip(ws).collect()
640    }
641
642    fn run_all(&mut self) -> Vec<((u64, u64), f64)> {
643        let mut ks = vec![];
644        let mut vs = vec![];
645        let mut ws = vec![];
646        PreferentialAttachmentIndexRunAll(self.inner.pin_mut(), &mut ks, &mut vs, &mut ws);
647        ks.into_iter().zip(vs).zip(ws).collect()
648    }
649}
650
651pub struct RandomLinkSampler;
652
653impl RandomLinkSampler {
654    pub fn by_count(g: &crate::Graph, num_links: u64) -> crate::Graph {
655        RandomLinkSamplerByCount(g, num_links).into()
656    }
657    pub fn by_percentage(g: &crate::Graph, percentage: f64) -> crate::Graph {
658        RandomLinkSamplerByPercentage(g, percentage).into()
659    }
660}
661
662pub struct ResourceAllocationIndex {
663    inner: UniquePtr<bridge::ResourceAllocationIndex>,
664}
665
666impl ResourceAllocationIndex {
667    pub fn new(g: &crate::Graph) -> Self {
668        Self {
669            inner: NewResourceAllocationIndex(g),
670        }
671    }
672}
673
674impl LinkPredictor for ResourceAllocationIndex {
675    fn set_graph(&mut self, g: &crate::Graph) {
676        self.inner.pin_mut().setGraph(g)
677    }
678
679    fn run(&mut self, u: u64, v: u64) -> f64 {
680        self.inner.pin_mut().run(u, v)
681    }
682
683    fn run_on(&mut self, pairs: &[(u64, u64)]) -> Vec<((u64, u64), f64)> {
684        let mut src = Vec::with_capacity(pairs.len());
685        let mut dst = Vec::with_capacity(pairs.len());
686        for (s, d) in pairs {
687            src.push(*s);
688            dst.push(*d);
689        }
690        let mut ks = vec![];
691        let mut vs = vec![];
692        let mut ws = vec![];
693        ResourceAllocationIndexRunOn(self.inner.pin_mut(), &src, &dst, &mut ks, &mut vs, &mut ws);
694        ks.into_iter().zip(vs).zip(ws).collect()
695    }
696
697    fn run_all(&mut self) -> Vec<((u64, u64), f64)> {
698        let mut ks = vec![];
699        let mut vs = vec![];
700        let mut ws = vec![];
701        ResourceAllocationIndexRunAll(self.inner.pin_mut(), &mut ks, &mut vs, &mut ws);
702        ks.into_iter().zip(vs).zip(ws).collect()
703    }
704}
705
706pub struct SameCommunityIndex {
707    inner: UniquePtr<bridge::SameCommunityIndex>,
708}
709
710impl SameCommunityIndex {
711    pub fn new(g: &crate::Graph) -> Self {
712        Self {
713            inner: NewSameCommunityIndex(g),
714        }
715    }
716}
717
718impl LinkPredictor for SameCommunityIndex {
719    fn set_graph(&mut self, g: &crate::Graph) {
720        self.inner.pin_mut().setGraph(g)
721    }
722
723    fn run(&mut self, u: u64, v: u64) -> f64 {
724        self.inner.pin_mut().run(u, v)
725    }
726
727    fn run_on(&mut self, pairs: &[(u64, u64)]) -> Vec<((u64, u64), f64)> {
728        let mut src = Vec::with_capacity(pairs.len());
729        let mut dst = Vec::with_capacity(pairs.len());
730        for (s, d) in pairs {
731            src.push(*s);
732            dst.push(*d);
733        }
734        let mut ks = vec![];
735        let mut vs = vec![];
736        let mut ws = vec![];
737        SameCommunityIndexRunOn(self.inner.pin_mut(), &src, &dst, &mut ks, &mut vs, &mut ws);
738        ks.into_iter().zip(vs).zip(ws).collect()
739    }
740
741    fn run_all(&mut self) -> Vec<((u64, u64), f64)> {
742        let mut ks = vec![];
743        let mut vs = vec![];
744        let mut ws = vec![];
745        SameCommunityIndexRunAll(self.inner.pin_mut(), &mut ks, &mut vs, &mut ws);
746        ks.into_iter().zip(vs).zip(ws).collect()
747    }
748}
749
750pub struct TotalNeighborsIndex {
751    inner: UniquePtr<bridge::TotalNeighborsIndex>,
752}
753
754impl TotalNeighborsIndex {
755    pub fn new(g: &crate::Graph) -> Self {
756        Self {
757            inner: NewTotalNeighborsIndex(g),
758        }
759    }
760}
761
762impl LinkPredictor for TotalNeighborsIndex {
763    fn set_graph(&mut self, g: &crate::Graph) {
764        self.inner.pin_mut().setGraph(g)
765    }
766
767    fn run(&mut self, u: u64, v: u64) -> f64 {
768        self.inner.pin_mut().run(u, v)
769    }
770
771    fn run_on(&mut self, pairs: &[(u64, u64)]) -> Vec<((u64, u64), f64)> {
772        let mut src = Vec::with_capacity(pairs.len());
773        let mut dst = Vec::with_capacity(pairs.len());
774        for (s, d) in pairs {
775            src.push(*s);
776            dst.push(*d);
777        }
778        let mut ks = vec![];
779        let mut vs = vec![];
780        let mut ws = vec![];
781        TotalNeighborsIndexRunOn(self.inner.pin_mut(), &src, &dst, &mut ks, &mut vs, &mut ws);
782        ks.into_iter().zip(vs).zip(ws).collect()
783    }
784
785    fn run_all(&mut self) -> Vec<((u64, u64), f64)> {
786        let mut ks = vec![];
787        let mut vs = vec![];
788        let mut ws = vec![];
789        TotalNeighborsIndexRunAll(self.inner.pin_mut(), &mut ks, &mut vs, &mut ws);
790        ks.into_iter().zip(vs).zip(ws).collect()
791    }
792}
793
794pub struct UDegreeIndex {
795    inner: UniquePtr<bridge::UDegreeIndex>,
796}
797
798impl UDegreeIndex {
799    pub fn new(g: &crate::Graph) -> Self {
800        Self {
801            inner: NewUDegreeIndex(g),
802        }
803    }
804}
805
806impl LinkPredictor for UDegreeIndex {
807    fn set_graph(&mut self, g: &crate::Graph) {
808        self.inner.pin_mut().setGraph(g)
809    }
810
811    fn run(&mut self, u: u64, v: u64) -> f64 {
812        self.inner.pin_mut().run(u, v)
813    }
814
815    fn run_on(&mut self, pairs: &[(u64, u64)]) -> Vec<((u64, u64), f64)> {
816        let mut src = Vec::with_capacity(pairs.len());
817        let mut dst = Vec::with_capacity(pairs.len());
818        for (s, d) in pairs {
819            src.push(*s);
820            dst.push(*d);
821        }
822        let mut ks = vec![];
823        let mut vs = vec![];
824        let mut ws = vec![];
825        UDegreeIndexRunOn(self.inner.pin_mut(), &src, &dst, &mut ks, &mut vs, &mut ws);
826        ks.into_iter().zip(vs).zip(ws).collect()
827    }
828
829    fn run_all(&mut self) -> Vec<((u64, u64), f64)> {
830        let mut ks = vec![];
831        let mut vs = vec![];
832        let mut ws = vec![];
833        UDegreeIndexRunAll(self.inner.pin_mut(), &mut ks, &mut vs, &mut ws);
834        ks.into_iter().zip(vs).zip(ws).collect()
835    }
836}
837
838pub struct VDegreeIndex {
839    inner: UniquePtr<bridge::VDegreeIndex>,
840}
841
842impl VDegreeIndex {
843    pub fn new(g: &crate::Graph) -> Self {
844        Self {
845            inner: NewVDegreeIndex(g),
846        }
847    }
848}
849
850impl LinkPredictor for VDegreeIndex {
851    fn set_graph(&mut self, g: &crate::Graph) {
852        self.inner.pin_mut().setGraph(g)
853    }
854
855    fn run(&mut self, u: u64, v: u64) -> f64 {
856        self.inner.pin_mut().run(u, v)
857    }
858
859    fn run_on(&mut self, pairs: &[(u64, u64)]) -> Vec<((u64, u64), f64)> {
860        let mut src = Vec::with_capacity(pairs.len());
861        let mut dst = Vec::with_capacity(pairs.len());
862        for (s, d) in pairs {
863            src.push(*s);
864            dst.push(*d);
865        }
866        let mut ks = vec![];
867        let mut vs = vec![];
868        let mut ws = vec![];
869        VDegreeIndexRunOn(self.inner.pin_mut(), &src, &dst, &mut ks, &mut vs, &mut ws);
870        ks.into_iter().zip(vs).zip(ws).collect()
871    }
872
873    fn run_all(&mut self) -> Vec<((u64, u64), f64)> {
874        let mut ks = vec![];
875        let mut vs = vec![];
876        let mut ws = vec![];
877        VDegreeIndexRunAll(self.inner.pin_mut(), &mut ks, &mut vs, &mut ws);
878        ks.into_iter().zip(vs).zip(ws).collect()
879    }
880}