icentral_scratch/
scratch.rs1crate::ix!();
2
3pub trait FindEdgeBccWithScratch<GH> {
4
5 fn find_edge_bcc_with_scratch(&mut self,
6 bcc: &mut BiconnectedComponentsScratch<GH>,
7 edge: &Edge)
8 -> Result<(),BetweennessCentralityError>;
9
10 fn find_edge_bcc_with_scratch_step(&mut self,
11 v: NodeId,
12 bcc: &mut BiconnectedComponentsScratch<GH>,
13 edge: &Edge)
14 -> Result<(),BetweennessCentralityError>;
15}
16
17pub struct BiconnectedComponentsScratch<GH> {
18 name: String,
19 articulation_point_map: ArticulationPointMap,
20 bcc_subgraph: GH,
21 bcc_fast_subgraph: SubGraph,
22}
23
24impl<GH> fmt::Debug for BiconnectedComponentsScratch<GH>
25
26where GH: GetPrintNodes + SetPrintNodes + Debug {
27
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29
30 let old = self.bcc_subgraph.get_print_nodes();
31
32 self.bcc_subgraph.set_print_nodes(false);
33
34 let res = f.debug_struct("BiconnectedComponentsScratch")
35 .field("bcc_subgraph",&self.bcc_subgraph)
36 .field("articulation_point_map", &self.articulation_point_map)
37 .finish();
38
39 self.bcc_subgraph.set_print_nodes(old);
40
41 res
42 }
43}
44
45impl<GH> CreateNamedEmpty for BiconnectedComponentsScratch<GH>
46
47where GH: CreateNamedEmpty {
48
49 fn empty(name: &str) -> Self {
50
51 let bcc_fast_subgraph_name = name![name, "bcc_fast_subgraph"];
52 let bcc_subgraph_name = name![name, "bcc_subgraph"];
53 let articulation_point_map_name = name![name, "articulation_point_map"];
54
55 Self {
56 name: name.to_owned(),
57 articulation_point_map: ArticulationPointMap::empty_mapped(articulation_point_map_name),
58 bcc_subgraph: GH::empty(bcc_subgraph_name),
59 bcc_fast_subgraph: SubGraph::empty(bcc_fast_subgraph_name),
60 }
61 }
62}
63
64impl<GH> BiconnectedComponentsScratch<GH>
65
66where GH
67: DebugIterationStep
68+ FindPruningCounts
69+ GetEdges
70+ GetNeighborsForNode
71+ GetNodeIdRange
72+ GetSigmaValueForNode
73+ HasEdge
74+ InitDebugIteration
75+ InsertEdge
76+ MappedNodes
77+ NumEdges
78+ NumNodes
79+ PairDependencyForNode
80+ ParentsForNode
81+ RemoveEdge
82{
83
84 delegate_to_subgraph!{bcc_fast_subgraph}
85
86 delegate_to_graphhash!{bcc_subgraph}
87
88 delegate_to_articulation_point_map!{}
89
90 pub fn bcc_fast_subgraph_reset_with_graphhash(&mut self) {
91 self.bcc_fast_subgraph.reset_with(&mut self.bcc_subgraph);
92 }
93
94 pub fn set_articulation_point_map(
95 &mut self,
96 other: ArticulationPointMap)
97 {
98 self.articulation_point_map = other;
99 }
100
101 pub fn bcc_subgraph(&self) -> &GH {
102 &self.bcc_subgraph
103 }
104
105 pub fn bcc_subgraph_mut(&mut self) -> &mut GH {
106 &mut self.bcc_subgraph
107 }
108
109 pub fn compute_bc(&mut self,
113 mut scores: &mut BetweennessScores,
114 max_iter: Option<usize>)
115 -> Result<(),BetweennessCentralityError>
116 {
117 for node in self.bcc_subgraph_mapped_nodes() {
126 scores.set_score_for_node(node, 0.0);
127 }
128
129 match max_iter {
131
132 Some(max_iter) => {
133
134
135 for node in self.bcc_fast_subgraph.limited_nodeid_range(Some(max_iter)) {
136
137 self.bc_iter(node, scores);
138 }
139 }
140
141 None => {
142
143 for node in self.bcc_fast_subgraph.nodeid_range() {
144
145 self.bc_iter(node, scores);
146 }
147
148 for (k,size_vec) in self.articulation_point_map.iter() {
149
150 if size_vec.len() > 1 {
151
152 let mut sub: usize = 0;
153
154 for i in 0..size_vec.len() {
155 sub += size_vec[i] * size_vec[i];
156 }
157
158 let vg_i: f64 = size_vec.iter().sum::<usize>() as f64;
159
160 scores.set_score_for_node(
161 *k,
162 scores.score_for_node(*k) + vg_i * vg_i - sub as f64
163 );
164 }
165 }
166
167 scores.halve();
168 }
169 }
170
171 Ok(())
172 }
173
174 pub fn bc_iter(&mut self,
175 s: NodeId,
176 mut scores: &mut BetweennessScores)
177 -> Result<(),BetweennessCentralityError>
178 {
179 let mut stack: Stack<NodeId> = default!();
180
181 self.bcc_fast_subgraph.reinit_maps();
182
183 self.bcc_fast_subgraph.set_path_count_for_node(s,1);
184 self.bcc_fast_subgraph.set_distance_for_node(s,0.0);
185
186 self.bcc_fast_subgraph.enqueue(s);
187
188 while let Some(v_i) = self.bcc_fast_subgraph.dequeue() {
189
190 stack.push(v_i);
191
192 let neighbors = self.bcc_fast_subgraph.neighbors(v_i);
193
194 for &v_n in neighbors.iter() {
195
196 if self.bcc_fast_subgraph.distance_is_infinite(v_n) {
197
198 self.bcc_fast_subgraph.enqueue(v_n);
199
200 self.bcc_fast_subgraph.set_distance_one_step_away(v_n,v_i);
201 }
202
203 if self.bcc_fast_subgraph.distance_is_one_step_away(v_n, v_i) {
204
205 self.bcc_fast_subgraph.increment_path_count_for_node_from(
206 v_n,
207 v_i
208 );
209
210 self.bcc_fast_subgraph.parents_for_node(v_n).push(v_i);
211 }
212 }
213 }
214
215 while let Some(v_n) = stack.pop() {
216
217 if self.has_both_articulation_points(s, v_n)
218 && s != v_n
219 {
220 let c_t: f64 = self.subgraphs_product_through_articulation_points(s, v_n);
221
222 self.bcc_fast_subgraph.increment_sigma_value_for_node(v_n, c_t);
223
224 let new_v_n: NodeId = self.bcc_fast_subgraph.label_map_inout(v_n);
225
226 scores.set_score_for_node(
227 new_v_n,
228 scores.score_for_node(new_v_n) + c_t
229 );
230 }
231
232 for i in 0..self.bcc_fast_subgraph.parents_for_node(v_n).len() {
233
234 let v_p: NodeId = self.bcc_fast_subgraph.parents_for_node(v_n)[i];
235
236 let sp_sn = self.bcc_fast_subgraph.path_count_ratio(v_p, v_n);
237
238 self.bcc_fast_subgraph.increment_pair_dependency_for_node(
239 v_p,
240 {
241 let pdn = self.bcc_fast_subgraph.pair_dependency_for_node(v_n);
242 sp_sn * (1.0 + pdn)
243 }
244 );
245
246 if self.has_articulation_point(s) {
247
248 self.bcc_fast_subgraph.set_sigma_value_for_node(
249 v_p,
250 {
251 let t0 = self.bcc_fast_subgraph.sigma_value_for_node(v_p);
252 let t1 = self.bcc_fast_subgraph.sigma_value_for_node(v_n);
253 t0 + t1 * sp_sn
254 }
255 );
256
257 let new_v_p: NodeId = self.bcc_fast_subgraph.label_map_inout(v_p);
258
259 scores.set_score_for_node(
260 new_v_p,
261 scores.score_for_node(new_v_p) + self.bcc_fast_subgraph.sigma_value_for_node(v_n) * sp_sn
262 );
263 }
264 }
265
266 if s != v_n {
267
268 let new_v_n: NodeId = self.bcc_fast_subgraph.label_map_inout(v_n);
269
270 scores.set_score_for_node(
271 new_v_n,
272 scores.score_for_node(new_v_n) + self.bcc_fast_subgraph.pair_dependency_for_node(v_n)
273 );
274 }
275
276 if self.has_articulation_point(s) {
277
278 let vg_s: f64 = self.subgraph_micentraltude_through_articulation_point(s);
279
280 let new_v_n: NodeId = self.bcc_fast_subgraph.label_map_inout(v_n);
281
282 scores.set_score_for_node(
283 new_v_n,
284 scores.score_for_node(new_v_n) + self.bcc_fast_subgraph.pair_dependency_for_node(v_n) * (vg_s as f64) * 2.0
285 );
286 }
287 }
288
289 Ok(())
290 }
291}