samyama_graph_algorithms/
common.rs1use std::collections::HashMap;
6
7pub type NodeId = u64;
9
10pub struct GraphView {
12 pub node_count: usize,
14 pub index_to_node: Vec<NodeId>,
16 pub node_to_index: HashMap<NodeId, usize>,
18
19 pub out_offsets: Vec<usize>,
22 pub out_targets: Vec<usize>,
24
25 pub in_offsets: Vec<usize>,
28 pub in_sources: Vec<usize>,
30
31 pub weights: Option<Vec<f64>>,
33}
34
35impl GraphView {
36 pub fn out_degree(&self, idx: usize) -> usize {
38 self.out_offsets[idx + 1] - self.out_offsets[idx]
39 }
40
41 pub fn in_degree(&self, idx: usize) -> usize {
43 self.in_offsets[idx + 1] - self.in_offsets[idx]
44 }
45
46 pub fn successors(&self, idx: usize) -> &[usize] {
48 let start = self.out_offsets[idx];
49 let end = self.out_offsets[idx + 1];
50 &self.out_targets[start..end]
51 }
52
53 pub fn predecessors(&self, idx: usize) -> &[usize] {
55 let start = self.in_offsets[idx];
56 let end = self.in_offsets[idx + 1];
57 &self.in_sources[start..end]
58 }
59
60 pub fn weights(&self, idx: usize) -> Option<&[f64]> {
62 self.weights.as_ref().map(|w| {
63 let start = self.out_offsets[idx];
64 let end = self.out_offsets[idx + 1];
65 &w[start..end]
66 })
67 }
68
69 pub fn from_adjacency_list(
71 node_count: usize,
72 index_to_node: Vec<NodeId>,
73 node_to_index: HashMap<NodeId, usize>,
74 outgoing: Vec<Vec<usize>>,
75 incoming: Vec<Vec<usize>>,
76 weights: Option<Vec<Vec<f64>>>,
77 ) -> Self {
78 let mut out_offsets = Vec::with_capacity(node_count + 1);
79 let mut out_targets = Vec::new();
80 let mut in_offsets = Vec::with_capacity(node_count + 1);
81 let mut in_sources = Vec::new();
82 let mut flat_weights = if weights.is_some() { Some(Vec::new()) } else { None };
83
84 out_offsets.push(0);
85 for (i, neighbors) in outgoing.into_iter().enumerate() {
86 out_targets.extend(neighbors);
87 out_offsets.push(out_targets.len());
88
89 if let Some(ref mut w_flat) = flat_weights {
90 if let Some(w_row) = weights.as_ref().map(|w| &w[i]) {
91 w_flat.extend(w_row.iter());
92 }
93 }
94 }
95
96 in_offsets.push(0);
97 for sources in incoming {
98 in_sources.extend(sources);
99 in_offsets.push(in_sources.len());
100 }
101
102 GraphView {
103 node_count,
104 index_to_node,
105 node_to_index,
106 out_offsets,
107 out_targets,
108 in_offsets,
109 in_sources,
110 weights: flat_weights,
111 }
112 }
113}