1crate::ix!();
2
3pub type BcMap = Arc<Mutex<BetweennessScores>>;
6
7pub struct GraphHash {
14
15 name: String,
16 nodes_map: NeighborsMap,
17 edges: Edges,
18
19 parents: ParentsMap,
25 path_counts: PathCounts,
26 new_path_counts: PathCounts,
27 inc_path_counts: PathCounts,
28 distances: DistanceMap,
29 pair_dependencies: PairDependencies,
30 new_pair_dependencies: PairDependencies,
31 sigmas: SigmaMap,
32 new_sigmas: SigmaMap,
33 visit_markers: VisitMarkers,
34 stack: NodeIdStack,
35 queue: NodeIdQueue,
36 print_nodes: AtomicBool,
37}
38
39delegate_to_parents!{GraphHash}
40delegate_to_distances!{GraphHash}
41delegate_to_sigmas!{GraphHash}
42delegate_to_sigmas!{GraphHash; new_sigmas}
43delegate_to_visit_markers!{GraphHash}
44delegate_to_bfs_queue!{GraphHash}
45delegate_to_bfs_stack!{GraphHash}
46delegate_to_pair_dependencies!{GraphHash}
47delegate_to_pair_dependencies!{GraphHash; new_pair_dependencies}
48delegate_to_path_counts!{GraphHash}
49delegate_to_path_counts!{GraphHash; new_path_counts}
50delegate_to_path_counts!{GraphHash; inc_path_counts}
51
52impl HasMapForNode for GraphHash {
53
54 delegate!{
55 to self.nodes_map {
56 fn has_map_for_node(&self, id: NodeId) -> bool;
57 }
58 }
59}
60
61impl GetNodeIdRange for GraphHash {
62
63 delegate!{
64 to self.nodes_map {
65 fn nodeid_range(&self) -> Vec<NodeId>;
66 }
67 }
68}
69
70impl PairDependencyForNode for GraphHash {
71
72 delegate!{
73 to self.pair_dependencies {
74 fn pair_dependency_for_node(&self, node: NodeId) -> f64;
75 }
76 }
77}
78
79impl ResetWith<GraphHash> for GraphHash {
80 fn reset_with(&mut self, g: &GraphHash) {
81 todo!();
82 }
83}
84
85impl SetPairDependencyForNode for GraphHash {
86
87 delegate!{
88 to self.pair_dependencies {
89 fn set_pair_dependency_for_node(&mut self, node: NodeId, val: f64);
90 }
91 }
92}
93
94impl PathCountForNode for GraphHash {
95
96 delegate!{
97
98 to self.path_counts {
99
100 fn path_count_for_node(&self, node: NodeId) -> usize;
101
102 fn path_count_for_node_ref(&self, node: NodeId) -> &usize;
103
104 fn path_count_for_node_mut(&mut self, node: NodeId) -> &mut usize;
105 }
106 }
107}
108
109impl HasEdge for GraphHash {
110
111 fn has_edge(&self, e: &Edge) -> bool {
112 self.edges.has_edge(e)
113 }
114}
115
116impl ParentsForNode for GraphHash {
117
118 fn parents_for_node(&self, v_n: NodeId) -> Vec<NodeId> {
119 self.parents.parents_for_node(v_n)
120 }
121}
122
123impl NumNodes for GraphHash {
124 fn num_nodes(&self) -> usize {
125 self.nodes_map.len()
126 }
127}
128
129impl NumEdges for GraphHash {
130 fn num_edges(&self) -> usize {
131 self.edges.len()
132 }
133}
134
135impl GetEdges for GraphHash {
136 fn edges(&self) -> &Edges {
137 &self.edges
138 }
139}
140
141impl MappedNodes for GraphHash {
142 fn mapped_nodes(&self) -> Vec<NodeId> {
143 self.nodes_map.mapped_nodes()
144 }
145}
146
147impl Named for GraphHash {
148
149 fn name(&self) -> Cow<'_,str> {
150 Cow::Borrowed(&self.name)
151 }
152}
153
154impl GraphHash {
155
156 delegate_to_neighbors_map!{}
157 delegate_to_edges!{}
158}
159
160impl<G> NewFromGraphRef<G> for GraphHash
161where G: GetEdges
162{
163
164 fn new_from_graph_ref(graph: &G, name: &str) -> Self {
165
166 let mut x = GraphHash::empty(name);
167
168 for edge in graph.edges().iter() {
169 x.insert_edge(&edge);
170 }
171
172 x
173 }
174}
175
176impl NewFromCycleVec for GraphHash {
177
178 fn new_from_cycle_vec(cycle_vec: &Vec<Cycle>, name: &str) -> Self {
179
180 let mut x = GraphHash::empty(name);
181
182 for i in NodeIdRange::new(0,cycle_vec.len()) {
183 x.insert_node(i);
184 }
185
186 for i in 0..cycle_vec.len() {
187
188 for j in 0..cycle_vec.len() {
189
190 if i != j && shared_vertex(&cycle_vec[i], &cycle_vec[j])
191 {
192 x.insert_edge(&Edge::new_with_ids(i, j));
193 }
194 }
195 }
196
197 x
198 }
199}
200
201impl fmt::Debug for GraphHash {
202
203 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
204
205 let binding = f.debug_struct("GraphHash");
206
207 let mut builder = binding;
208
209 builder.field("edges", &self.edges);
210
211 if self.print_nodes.load(atomic::Ordering::SeqCst) {
212
213 builder.field("nodes_map", &self.nodes_map);
214
215 }
216
217 builder.finish()
218 }
219}
220
221impl SpawnScores for GraphHash {
222
223 fn spawn_scores(&self) -> BetweennessScores
224 {
225 let scores_name = name![self.name(), "scores"];
226
227 BetweennessScores::new_from_graph_ref(self, scores_name)
228 }
229}
230
231impl BrandesIterInit for GraphHash {
232
233 fn brandes_iter_init(&mut self, s: NodeId)
234 {
235 self.reinit_maps();
236
237 self.stack.clear();
238
239 self.path_counts.set_path_count_for_node(s,1);
240
241 self.distances.set_distance_for_node(s,0.0);
242
243 self.enqueue(s);
244 }
245}
246
247impl BrandesIterUpdateDistancesAndPathForNeighbors for GraphHash {
248
249 fn brandes_iter_update_dist_and_path_for_neighbors(&mut self, s: NodeId)
250 {
251 while let Some(v) = self.dequeue() {
252
253 self.stack.push(v);
254
255 self.update_dist_and_path_for_neighbors(v);
256 }
257 }
258}
259
260impl BrandesIterUpdatePairDependenciesAndFill for GraphHash {
261
262 fn brandes_iter_update_pair_dependencies_and_fill(
263 &mut self,
264 s: NodeId,
265 scores: &mut BetweennessScores)
266 -> Result<(),BetweennessCentralityError>
267 {
268 for i in (0..=self.stack.len() - 1).rev() {
269
270 let w: NodeId = self.stack_node_at_index(i);
271
272 self.update_parent_pair_dependencies_and_increment_score_for_node(w, s, scores);
273 }
274
275 Ok(())
276 }
277}
278
279impl SetPrintNodes for GraphHash {
280
281 fn set_print_nodes(&self, val: bool) {
282 self.print_nodes.store(val, atomic::Ordering::SeqCst);
283 }
284}
285
286impl GetPrintNodes for GraphHash {
287
288 fn get_print_nodes(&self) -> bool {
289 self.print_nodes.load(atomic::Ordering::SeqCst)
290 }
291}
292
293impl GetNeighborsForNode for GraphHash {
294
295 fn neighbors(&self, id: NodeId)
296 -> Vec<NodeId>
297 {
298 self.nodes_map.neighbors(id)
299 }
300}
301
302impl ReinitMapsForNode for GraphHash {
303
304 fn reinit_maps_for_node(&mut self, k: NodeId)
305 {
306 self.parents.set_parents_for_node(k, vec![]);
307
308 self.path_counts.set_path_count_for_node(k, 0);
309 self.new_path_counts.set_path_count_for_node(k, 0);
310
311 self.distances.set_distance_for_node(k, -1.0);
312
313 self.pair_dependencies.set_pair_dependency_for_node(k, 0.0);
314 self.new_pair_dependencies.set_pair_dependency_for_node(k, 0.0);
315
316 self.set_sigma_value_for_node(k, 0.0);
317 self.new_sigmas_set_sigma_value_for_node(k, 0.0);
318
319 self.inc_path_counts.set_path_count_for_node(k, 0);
320
321 self.visit_markers.unvisit(k);
322 }
323}
324
325impl ReinitMaps for GraphHash {
326
327 fn reinit_maps(&mut self)
328 {
329 for k in self.nodes_map.mapped_nodes() {
330 self.reinit_maps_for_node(k);
331 }
332 }
333}
334
335impl InsertNode for GraphHash {
336
337 fn insert_node(&mut self, id: NodeId)
338 {
339 self.nodes_map.add_isolated_node(id);
340 }
341}
342
343impl InsertEdge for GraphHash {
344
345 fn insert_edge(&mut self, edge: &Edge)
346 -> Result<(),BetweennessCentralityError>
347 {
348 let redge = edge.reversed();
349
350 if self.edges.has_edge(&edge)
351 || self.edges.has_edge(&redge)
352 {
353 return Ok(());
354
355 } else {
356
357 self.edges.insert_edge(*edge);
358 }
359
360 self.insert_node(edge.src);
361 self.insert_node(edge.dst);
362
363 self.nodes_map.add_edge(&edge);
364
365 Ok(())
366 }
367}
368
369impl RemoveEdge for GraphHash {
370
371 fn remove_edge(&mut self, edge: &Edge)
372 -> Result<(),BetweennessCentralityError>
373 {
374 self.edges.remove_edge(&edge);
375
376 let redge = edge.reversed();
377
378 self.edges.remove_edge(&redge);
379
380 self.nodes_map.unlink_edge(edge);
381
382 Ok(())
383 }
384}
385
386impl GetConnectedComponentSizes for GraphHash {
387
388 fn conn_comp_sizes(&self)
394 -> Result<Vec<i32>,BetweennessCentralityError>
395 {
396 let mut out_vec = vec![];
397
398 let visited_map_name = name![
399 self.name(),
400 "conn_comp_sizes::visited_map"
401 ];
402
403 let mut visited_map = VisitMarkers::new_from_nodes(
404 self.nodes_map.mapped_nodes(),
405 &visited_map_name
406 );
407
408 for id in visited_map.iter_unvisited() {
409
410 self.conn_comp_sizes_step(
411 &mut visited_map,
412 id,
413 &mut out_vec
414 );
415 }
416
417 Ok(out_vec)
418 }
419}
420
421impl ExtendWith<GraphHash> for GraphHash {
422
423 type Error = BetweennessCentralityError;
424
425 fn extend_with(&mut self, other: &GraphHash)
426 -> Result<(),Self::Error>
427 {
428 self.nodes_map.extend_with(
429 &other.nodes_map
430 );
431
432 self.edges.extend(
433 &other.edges
434 );
435
436 Ok(())
437 }
438}
439
440impl InitDebugIteration for GraphHash {
441
442 fn init_dbg_iteration(&mut self, source: NodeId) {
443
444 self.reinit_maps();
445 self.path_counts.set_path_count_for_node(source,1);
446 self.distances.set_distance_for_node(source,0.0);
447 self.enqueue(source);
448 }
449}
450
451impl DebugIterationStep for GraphHash {
452
453 fn dbg_iteration_step(&mut self, v_s: &mut Vec<NodeId>)
454 -> Result<(),BetweennessCentralityError>
455 {
456 while let Some(v_i) = self.dequeue() {
457
458 v_s.push(v_i);
459
460 self.update_dist_and_path_for_neighbors(v_i);
461 }
462
463 Ok(())
464 }
465}
466
467impl RemoveBridges for GraphHash {
468
469 fn remove_bridges(&mut self, bridge_vec: Vec<Edge>) {
470
471 debug!("removing bridges...");
472
473 for bridge in bridge_vec.iter() {
474
475 self.remove_edge(&bridge);
476 }
477 }
478}
479
480impl FindConnectedComponents<GraphHash> for GraphHash {
481
482 type Error = BetweennessCentralityError;
483
484 fn find_conn_comp(&mut self)
485 -> Result<Vec<GraphHash>,Self::Error>
486 {
487 debug!("finding connected components...");
488
489 let mut out_vec = vec![];
490
491 let visited_map_name = name![self.name(), "find_conn_comp::visited_map"];
492
493 let mut visited_map = VisitMarkers::new_from_nodes(
494 self.nodes_map.mapped_nodes(),
495 visited_map_name
496 );
497
498 for id in self.nodes_map.mapped_nodes() {
499
500 if visited_map.unvisited(id) {
501
502 let gh_name = name![self.name(), format!("graphhash_for_id{}", id)];
503
504 let gh = GraphHash::new_via_bfs_from_id(
505 gh_name,
506 self,
507 id,
508 &mut visited_map
509 );
510
511 out_vec.push(gh);
512 }
513 }
514
515 Ok(out_vec)
516 }
517}
518
519impl CreateNamedEmpty for GraphHash {
520
521 fn empty(name: &str) -> Self {
522
523 let nodes_map_name = name![name, "nodes_map"];
524 let edges_name = name![name, "edges"];
525 let parents_name = name![name, "parents"];
526 let path_counts_name = name![name, "path_counts"];
527 let new_path_counts_name = name![name, "new_path_counts"];
528 let inc_path_counts_name = name![name, "inc_path_counts"];
529 let distances_name = name![name, "distances"];
530 let pair_dependencies_name = name![name, "pair_dependencies"];
531 let new_pair_dependencies_name = name![name, "new_pair_dependencies"];
532 let sigmas_name = name![name, "sigmas"];
533 let new_sigmas_name = name![name, "new_sigmas"];
534 let visit_markers_name = name![name, "visit_markers"];
535 let stack_name = name![name, "stack"];
536 let queue_name = name![name, "queue"];
537
538 Self {
539 name: name.to_owned(),
540 nodes_map: NeighborsMap::empty_mapped(nodes_map_name),
541 edges: Edges::empty(edges_name),
542 parents: ParentsMap::empty_mapped(parents_name),
543 path_counts: PathCounts::empty_mapped(path_counts_name),
544 new_path_counts: PathCounts::empty_mapped(new_path_counts_name),
545 inc_path_counts: PathCounts::empty_mapped(inc_path_counts_name),
546 distances: DistanceMap::empty_mapped(distances_name),
547 pair_dependencies: PairDependencies::empty_mapped(pair_dependencies_name),
548 new_pair_dependencies: PairDependencies::empty_mapped(new_pair_dependencies_name),
549 sigmas: SigmaMap::empty_mapped(sigmas_name),
550 new_sigmas: SigmaMap::empty_mapped(new_sigmas_name),
551 visit_markers: VisitMarkers::empty_mapped(visit_markers_name),
552 stack: NodeIdStack::empty(stack_name),
553 queue: NodeIdQueue::empty(queue_name),
554 print_nodes: AtomicBool::new(false),
555 }
556 }
557}
558
559impl GraphHash {
560
561 pub fn fill_edges_from_bfs(
565 &mut self,
566 parent: &GraphHash,
567 id: NodeId,
568 visited_map: &mut VisitMarkers)
569 {
570 let mut q = NodeIdQueue::empty("fill_edges_from_bfs::queue");
571
572 q.enqueue(id);
573
574 while let Some(node) = q.dequeue() {
575
576 let nbrs_vec = parent.nodes_map.neighbors(node);
577
578 for &nbr in nbrs_vec.iter() {
579
580 self.insert_edge(&Edge::new(node, nbr));
581
582 if visited_map.unvisited(nbr) {
583
584 visited_map.visit(nbr);
585
586 q.enqueue(nbr);
587 }
588 }
589 }
590 }
591
592 pub fn new_via_bfs_from_id(
593 name: &str,
594 parent: &GraphHash,
595 id: NodeId,
596 visited_map: &mut VisitMarkers) -> Self {
597
598 let mut gh: GraphHash = GraphHash::empty(name);
599
600 visited_map.visit(id);
601
602 gh.insert_node(id);
603
604 gh.fill_edges_from_bfs(
605 parent,
606 id,
607 visited_map
608 );
609
610 gh
611 }
612
613 pub fn maybe_set_distance_for_neighbor(
614 &mut self,
615 w: NodeId,
616 v: NodeId)
617 {
618 if self.distances.is_infinite(w) {
619
620 self.enqueue(w);
621
622 self.distances.set_distance_for_node(
623 w,
624 self.distance(v) + 1.0
625 );
626 }
627 }
628
629 pub fn maybe_increment_path_count_and_add_parent_for_neighbor(
630 &mut self,
631 w: NodeId,
632 v: NodeId)
633 {
634 if self.distances.is_one_step_away(w, v) {
635
636 self.path_counts.increment_path_count_for_node_from(w,v);
637
638 self.parents.add_parent(w, v);
639 }
640 }
641
642 pub fn update_dist_and_path_for_neighbors(
643 &mut self,
644 v: NodeId)
645 {
646 let nbr_vec = self.neighbors(v);
647
648 for &w in nbr_vec.iter() {
649
650 self.maybe_set_distance_for_neighbor(w, v);
651
652 self.maybe_increment_path_count_and_add_parent_for_neighbor(w, v);
653 }
654 }
655
656 pub fn update_pair_dependencies(&mut self, w: NodeId, v: NodeId) {
657
658 let v_paths = self.path_counts.path_count_for_node(v) as f64;
659 let w_paths = self.path_counts.path_count_for_node(w) as f64;
660
661 let paths_ratio = v_paths / w_paths;
662
663 let w_pair_dependencies = self.pair_dependencies.pair_dependency_for_node(w);
664
665 self.pair_dependencies.increment_pair_dependency_for_node(
666 v,
667 paths_ratio * (1.0 + w_pair_dependencies)
668 );
669 }
670
671 pub fn update_parent_pair_dependencies_and_increment_score_for_node(
672 &mut self,
673 w: NodeId,
674 s: NodeId,
675 scores: &mut BetweennessScores)
676 {
677 let parents = self.parents.parents_for_node(w);
678
679 for v in parents {
680
681 self.update_pair_dependencies(w,v);
682 }
683
684 if w != s {
685
686 scores.increase_score_for_node(
687 w,
688 self.pair_dependencies.pair_dependency_for_node(w)
689 );
690 }
691 }
692
693 pub fn conn_comp_sizes_step(&self,
694 visited_map: &mut VisitMarkers,
695 id: NodeId,
696 out_vec: &mut Vec<i32>)
697 {
698 visited_map.visit(id);
699
700 out_vec.push(1);
701
702 let queue_name = name![self.name(), "conn_comp_sizes_step::queue"];
703
704 let mut q = NodeIdQueue::empty(queue_name);
709
710 q.enqueue(id);
711
712 while let Some(node) = q.dequeue() {
713
714 let nbrs_vec = self.nodes_map.neighbors(node);
715
716 for &nbr in nbrs_vec.iter() {
717
718 if visited_map.unvisited(nbr) {
719
720 visited_map.visit(nbr);
721
722 q.enqueue(nbr);
723
724 *out_vec.last_mut().unwrap() += 1;
725 }
726 }
727 }
728 }
729
730 pub fn find_single_source_shortest_paths_step(
731 &self,
732 v: NodeId,
733 id: NodeId,
734 single_source_shortest_paths: &mut DistanceMap,
735 queue: &mut NodeIdQueue)
736 {
737 let nbr_vec = self.neighbors(v);
738
739 for &nbr in nbr_vec.iter() {
740
741 if single_source_shortest_paths.is_infinite(nbr) {
742
743 single_source_shortest_paths.set_distance_for_node(
744 nbr,
745 single_source_shortest_paths.distance(v) + 1.0
746 );
747
748 queue.enqueue(nbr);
749 }
750 }
751 }
752}
753
754impl FindSingleSourceShortestPaths for GraphHash {
755
756 fn find_single_source_shortest_paths(&self, id: NodeId)
757 -> Result<DistanceMap,BetweennessCentralityError>
758 {
759 let queue_name = format!("sssp_queue_for_{}", id);
760 let distance_map_name = format!("sssp_distance_map_for_{}", id);
761
762 let mut single_source_shortest_paths = DistanceMap::new_from_nodes(
763 self.nodes_map.mapped_nodes(),
764 &distance_map_name
765 );
766
767 let mut queue = NodeIdQueue::new(id, &queue_name);
768
769 single_source_shortest_paths.set_distance_for_node(id,0.0);
770
771 while let Some(v) = queue.dequeue() {
772
773 self.find_single_source_shortest_paths_step(
774 v,
775 id,
776 &mut single_source_shortest_paths,
777 &mut queue
778 );
779 }
780
781 Ok(single_source_shortest_paths)
782 }
783}
784
785impl FindPruningCounts for GraphHash {
786
787 fn find_pruning_counts_exp(&mut self,
788 src: NodeId,
789 dst: NodeId)
790 -> Result<(i32,i32,i32),BetweennessCentralityError>
791 {
792 let edge = Edge::new(src,dst);
793
794 let insert: bool = self.has_edge(&edge);
799
800 self.remove_edge(&edge);
801
802 let src_distances = self.find_single_source_shortest_paths(edge.src)?;
803 let dst_distances = self.find_single_source_shortest_paths(edge.dst)?;
804
805 let mut d0 = 0;
806 let mut d1 = 0;
807 let mut d2 = 0;
808
809 for node in self.nodes_map.mapped_nodes() {
810
811 let src_dist = src_distances.distance(node);
812 let dst_dist = dst_distances.distance(node);
813
814 let diff: f64 = src_dist - dst_dist;
815 let abs_diff: f64 = diff.abs();
816
817 match abs_diff {
818 0.0 => d0 += 1,
819 1.0 => d1 += 1,
820 _ => d2 += 1,
821 }
822 }
823
824 if insert {
825 self.insert_edge(&edge);
826 }
827
828 Ok((d0,d1,d2))
829 }
830}