Skip to main content

icentral_component/
component.rs

1crate::ix!();
2
3pub trait FindEdgeBccWithComponent<GH> {
4
5    fn find_edge_bcc_with_component_step(
6        &mut self, 
7        gh:        &GH,
8        v:         NodeId,
9        component: &mut Component,
10        e:         &Edge) 
11    -> Result<(),BetweennessCentralityError>;
12
13    fn find_edge_bcc_with_component(
14        &mut self, 
15        component: &mut Component,
16        e:         &Edge) 
17    -> Result<(),BetweennessCentralityError>;
18}
19
20//-------------------------------------------[icentral/src/component_t.h]
21
22#[derive(Debug,Clone,PartialEq,Eq)]
23pub enum CompType {
24    BiconnectedComponent, 
25    MinimumUnionCycle, 
26    Graph
27}
28
29impl Default for CompType {
30
31    fn default() -> Self {
32        Self::BiconnectedComponent
33    }
34}
35
36/**
37 | The component (subgraph along with other
38 | needed information) that bc computation blocks
39 | operate on.
40 | 
41 | Could be a BiconnectedComponents, an
42 |  MinimumUnionCycle, or just a graph.
43 |
44 */
45pub struct Component {
46    name:                   String,
47    subgraph:               SubGraph,
48    articulation_point_map: ArticulationPointMap,
49    comp_type:              CompType,
50}
51
52impl Component {
53
54    delegate_to_articulation_point_map!{}
55
56    pub fn new_from_graph_ref<G>(g: &G, name: &str) -> Self 
57        where G: NumNodes + MappedNodes + GetNodeIdRange + GetNeighborsForNode + GetEdges
58    {
59        debug!("creating new Component named {} with CompType::Graph from Graph of num_nodes: {}", name, g.num_nodes());
60
61        let subgraph_name               = name![name, "subgraph"];
62        let articulation_point_map_name = name![name, "articulation_point_map"];
63
64        Self {
65            name:                   name.to_owned(),
66            subgraph:               SubGraph::new_from_graph_ref(g, subgraph_name),
67            articulation_point_map: ArticulationPointMap::empty_mapped(articulation_point_map_name),
68            comp_type:              CompType::Graph,
69        }
70    }
71
72    pub fn new_biconnected(name: &str) -> Self {
73
74        let subgraph_name               = name![name, "subgraph"];
75        let articulation_point_map_name = name![name, "articulation_point_map"];
76
77        Component {
78            name:                   name.to_owned(),
79            subgraph:               SubGraph::empty(subgraph_name),
80            articulation_point_map: ArticulationPointMap::empty_mapped(articulation_point_map_name),
81            comp_type:              CompType::BiconnectedComponent,
82        }
83    }
84
85    pub fn subgraph(&self) -> &SubGraph {
86        &self.subgraph
87    }
88
89    pub fn ty(&self) -> CompType {
90        self.comp_type.clone()
91    }
92
93    pub fn create_distance_maps(&self, edge: &Edge)
94    -> Result<(DistanceMap, DistanceMap),BetweennessCentralityError>
95    {
96        Ok(self.subgraph.create_distance_maps(edge)?)
97    }
98
99    delegate! {
100        to self.subgraph {
101
102            #[call(reset_with)]
103            pub fn reset_subgraph_with<GH>(&mut self, gh: &mut GH)
104                where GH: NumNodes + GetNodeIdRange + GetNeighborsForNode + GetEdges;
105
106            pub fn label_map_outin(&self, out: NodeId) -> NodeId;
107
108            pub fn label_map_inout(&self, out: NodeId) -> NodeId;
109
110            pub fn neighbors(&self, n: NodeId) -> Vec<NodeId>;
111
112            #[call(num_nodes)]
113            pub fn num_nodes(&self) -> usize;
114
115            pub fn insert_edge_between_nodes(&mut self, src: NodeId, dst: NodeId);
116
117            pub fn insert_edge(&mut self, edge: &Edge);
118
119            pub fn find_single_source_shortest_paths(
120                &self, 
121                s: NodeId) 
122            -> Result<DistanceMap,BetweennessCentralityError>;
123        }
124    }
125
126    pub fn remap_articulation_point_map(&mut self) {
127
128        let mut new_articulation_point_map 
129            = ArticulationPointMap::empty_mapped(&self.articulation_point_map.name());
130
131        for (k,v) in self.articulation_point_map.iter() {
132
133            let new_v: NodeId = self.label_map_outin(*k);
134
135            new_articulation_point_map.map_articulation_point(new_v,v);
136        }
137
138        self.articulation_point_map = new_articulation_point_map;
139    }
140}
141
142impl fmt::Debug for Component {
143
144    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145
146        let binding     = f.debug_struct("Component");
147        let mut builder = binding;
148
149        builder
150            .field("subgraph",  &self.subgraph.debug_without_nodes())
151            .field("comp_type", &self.comp_type);
152
153        for (k,v) in self.articulation_point_map.iter() {
154
155            let tag = format!{"articulation_point [{}]",k};
156
157            let point: String = v.iter().map(|x| x.to_string()).collect::<Vec<String>>().join(" ");
158
159            builder.field(
160                tag.as_str(), 
161                &point
162            );
163        }
164
165        builder.finish()
166    }
167}