uni_algo/algo/algorithms/
apsp.rs1use crate::algo::GraphProjection;
7use crate::algo::algorithms::Algorithm;
8use rayon::prelude::*;
9use std::collections::VecDeque;
10use std::sync::Mutex;
11use uni_common::core::id::Vid;
12
13pub struct AllPairsShortestPath;
14
15#[derive(Debug, Clone, Default)]
16pub struct AllPairsShortestPathConfig;
17
18pub struct AllPairsShortestPathResult {
19 pub distances: Vec<(Vid, Vid, u32)>, }
21
22impl Algorithm for AllPairsShortestPath {
23 type Config = AllPairsShortestPathConfig;
24 type Result = AllPairsShortestPathResult;
25
26 fn name() -> &'static str {
27 "allPairsShortestPath"
28 }
29
30 fn run(graph: &GraphProjection, _config: Self::Config) -> Self::Result {
31 let n = graph.vertex_count();
32 if n == 0 {
33 return AllPairsShortestPathResult {
34 distances: Vec::new(),
35 };
36 }
37
38 let mut results = Vec::new();
41 let results_mutex = Mutex::new(&mut results);
42
43 (0..n as u32).into_par_iter().for_each(|s| {
44 let mut q = VecDeque::with_capacity(n);
45 let mut d = vec![-1; n];
46
47 d[s as usize] = 0;
48 q.push_back(s);
49
50 let mut local_results = Vec::new();
51
52 while let Some(u) = q.pop_front() {
53 let dist_u = d[u as usize];
54
55 if u != s {
56 local_results.push((s, u, dist_u as u32));
57 }
58
59 for &v in graph.out_neighbors(u) {
60 if d[v as usize] == -1 {
61 d[v as usize] = dist_u + 1;
62 q.push_back(v);
63 }
64 }
65 }
66
67 if !local_results.is_empty() {
68 let mut guard = results_mutex.lock().unwrap_or_else(|e| e.into_inner());
69 let src_vid = graph.to_vid(s);
70 for (_src_idx, tgt_idx, dist) in local_results {
71 guard.push((src_vid, graph.to_vid(tgt_idx), dist));
73 }
74 }
75 });
76
77 AllPairsShortestPathResult { distances: results }
78 }
79}