Aleph-w  1.9
General library for algorithms and data structures
tpl_components.H
1 
2 /* Aleph-w
3 
4  / \ | | ___ _ __ | |__ __ __
5  / _ \ | |/ _ \ '_ \| '_ \ ____\ \ /\ / / Data structures & Algorithms
6  / ___ \| | __/ |_) | | | |_____\ V V / version 1.9b
7  /_/ \_\_|\___| .__/|_| |_| \_/\_/ https://github.com/lrleon/Aleph-w
8  |_|
9 
10  This file is part of Aleph-w library
11 
12  Copyright (c) 2002-2018 Leandro Rabindranath Leon & Alejandro Mujica
13 
14  This program is free software: you can redistribute it and/or modify
15  it under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  This program is distributed in the hope that it will be useful, but
20  WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with this program. If not, see <https://www.gnu.org/licenses/>.
26 */
27 # ifndef TPL_COMPONENTS_H
28 # define TPL_COMPONENTS_H
29 
30 # include <tpl_agraph.H>
31 
32 namespace Aleph {
33 
34 
45  template <class GT, class SA = Dft_Show_Arc<GT> >
47 {
48  SA sa;
49  const GT * gptr = nullptr;
50  size_t count = 0;
51 
52 public:
53 
54  Build_Subgraph(SA __sa = SA())
55  noexcept(std::is_nothrow_move_assignable<SA>::value)
56  : sa(__sa) { /* empty */ }
57 
58 private:
59 
60  void build_subgraph(GT & sg, typename GT::Node * g_src)
61  {
62  if (IS_NODE_VISITED(g_src, Build_Subtree))
63  return;
64 
65  NODE_BITS(g_src).set_bit(Build_Subtree, true); // g_src visitado
66  ++count;
67 
68  auto sg_src = mapped_node <GT> (g_src);
69  if (sg_src == nullptr) // ¿está mapeado g_src?
70  { // No, cree imagen de g_src en el subgrafo sg y mapee
71  sg_src = sg.insert_node(g_src->get_info());
72  GT::map_nodes(g_src, sg_src);
73  }
74 
75  for (Node_Arc_Iterator<GT, SA> i(g_src, sa); // explore desde g_src
76  i.has_curr(); i.next_ne())
77  {
78  auto arc = i.get_current_arc_ne();
79  if (IS_ARC_VISITED(arc, Build_Subtree))
80  continue; // avance próximo arco
81 
82  ARC_BITS(arc).set_bit(Build_Subtree, true); // arc visitado
83 
84  auto g_tgt = i.get_tgt_node(); // destino de arc
85  auto sg_tgt = mapped_node <GT> (g_tgt);
86  if (sg_tgt == nullptr) // ¿está mapeado en sg?
87  { // no, hay que mapearlo e insertarlo en el subgrafo sg
88  sg_tgt = sg.insert_node(g_tgt->get_info());
89  GT::map_nodes(g_tgt, sg_tgt);
90  }
91 
92  // tenemos nodos en subgrafo, insertamos arco y mapeamos
93  auto sg_arc = sg.insert_arc(sg_src, sg_tgt, arc->get_info());
94 
95  GT::map_arcs(arc, sg_arc);
96 
97  build_subgraph(sg, g_tgt);
98  }
99  }
100 
101  template <template <class> class List>
102  void build_subgraph(List<typename GT::Node*> & l, typename GT::Node * p)
103  {
104  if (IS_NODE_VISITED(p, Build_Subtree))
105  return;
106 
107  NODE_BITS(p).set_bit(Build_Subtree, true); // g_src visitado
108  ++count;
109  l.append(p);
110 
111  for (Node_Arc_Iterator<GT, SA> it(p, sa); // explore desde g_src
112  count < gptr->get_num_nodes() and it.has_curr(); it.next_ne())
113  {
114  auto arc = it.get_current_arc_ne();
115  if (IS_ARC_VISITED(arc, Build_Subtree))
116  continue; // avance próximo arco
117 
118  ARC_BITS(arc).set_bit(Build_Subtree, true); // arc visitado
119  build_subgraph(l, it.get_tgt_node());
120  }
121  }
122 
123  public:
124 
141  void operator () (const GT & g, GT & sg, typename GT::Node * g_src)
142  {
143  gptr = &g;
144  count = 0;
145  build_subgraph (sg, g_src);
146  }
147 
148  GT operator () (const GT & g, typename GT::Node * src)
149  {
150  GT sg;
151  gptr = &g;
152  count = 0;
153  build_subgraph(sg, src);
154  return sg;
155  }
156 
173  typename GT::Node * src)
174  {
175  gptr = &g;
176  count = 0;
177  build_subgraph<DynList>(list, src);
178  }
179 };
180 
181 
206  template <class GT, class SA = Dft_Show_Arc<GT> >
208 {
209  SA sa;
210 
211 public:
212 
213  Inconnected_Components(SA __sa = SA())
214  noexcept(std::is_nothrow_move_assignable<SA>::value)
215  : sa(__sa) { /* empty */ }
216 
217  template <template <class> class List>
218  void compute_blocks(const GT & g, List <GT> & list)
219  {
220  g.reset_nodes();
221  g.reset_arcs();
222  size_t count = 0; // contador de nodos visitados
223  for (typename GT::Node_Iterator it(g); // recorrer nodos de g
224  count < g.get_num_nodes() and it.has_curr(); it.next_ne())
225  {
226  auto curr = it.get_current_node_ne();
227  if (IS_NODE_VISITED(curr, Build_Subtree))
228  continue;
229 
230  GT & subgraph = list.append(GT()); // grafo insertado en list
231 
232  Build_Subgraph <GT, SA> build(sa);
233  build(g, subgraph, curr);
234 
235  count += subgraph.get_num_nodes();
236  }
237  }
238 
239  template <template <class> class List>
240  void compute_lists(const GT & g, List<List<typename GT::Node*> > & list)
241  {
242  g.reset_nodes();
243  g.reset_arcs();
244  size_t count = 0; // contador de nodos visitados
245  for (typename GT::Node_Iterator i(g); // recorrer nodos de g
246  count < g.get_num_nodes() and i.has_curr(); i.next_ne())
247  {
248  auto curr = i.get_current_node_ne();
249  if (IS_NODE_VISITED(curr, Build_Subtree))
250  continue;
251 
252  // crear subgrafo componente inconexo conectado por curr_node
253  auto & l = list.append(List<typename GT::Node*>());
254 
255  Build_Subgraph <GT, SA> build(sa);
256  build(g, l, curr);
257 
258  count += l.size();
259  }
260  }
261 
276  void operator () (const GT & g, DynList <GT> & list)
277  {
278  compute_blocks<DynList>(g, list);
279  }
280 
296  {
297  compute_lists<DynList>(g, list);
298  }
299 };
300 
301 
302 } // end namespace Aleph
303 
304 # endif // TPL_COMPONENTS_H
#define IS_NODE_VISITED(p, bit)
Definition: aleph-graph.H:327
void map_arcs(typename GTS::Arc *p, typename GTT::Arc *q) noexcept
Definition: tpl_graph.H:3445
Definition: tpl_components.H:46
#define IS_ARC_VISITED(p, bit)
Definition: aleph-graph.H:360
void map_nodes(typename GTS::Node *p, typename GTT::Node *q) noexcept
Definition: tpl_graph.H:3419
Definition: ah-comb.H:35
#define NODE_BITS(p)
Definition: aleph-graph.H:305
#define ARC_BITS(p)
Definition: aleph-graph.H:351
Definition: tpl_components.H:207
Definition: ahDry.H:41
Definition: tpl_graph.H:1177
void operator()(const GT &g, GT &sg, typename GT::Node *g_src)
Definition: tpl_components.H:141
Definition: List.H:49

Leandro Rabindranath León