Aleph-w  1.5a.2
Biblioteca general de algoritmos y estructuras de datos
 Todo Clases Archivos Funciones Variables 'typedefs' Enumeraciones Amigas Grupos Páginas
kosaraju.H
1 # ifndef KOSARAJU_H
2 # define KOSARAJU_H
3 
4 # include <tpl_graph_utils.H>
5 
6 namespace Aleph {
7 
8  template <class GT, class SA> inline static
9 void __dfp(GT & g, typename GT::Node * p, DynArray<typename GT::Node*> & df)
10 {
11  if (IS_NODE_VISITED(p, Depth_First))
12  return;
13 
14  NODE_BITS(p).set_bit(Depth_First, true);
15 
16  // recorre en profundidad los arcos de p
17  for (Node_Arc_Iterator<GT,SA> it(p); it.has_current(); it.next())
18  {
19  typename GT::Arc * a = it.get_current_arc();
20  if (IS_ARC_VISITED(a, Depth_First))
21  continue;
22 
23  ARC_BITS(a).set_bit(Depth_First, true);
24 
25  __dfp<GT,SA>(g, it.get_tgt_node(), df);
26  }
27  df.append(p); // asignación de df(p) en sufijo
28  NODE_COUNTER(p) = df.size();
29 }
30 
31  /* Recorre el grafo invertido e inserta los nodos alcanzables en el
32  sub-grafo blk. A cada bloque le coloca el color color
33 
34  */
35  template <class GT, class SA> inline static
36 void __dfp(GT & g, typename GT::Node * p, GT & blk, const int & color)
37 {
38  if (IS_NODE_VISITED(p, Depth_First))
39  return;
40 
41  NODE_BITS(p).set_bit(Depth_First, true);
42 
43  typename GT::Node * q = blk.insert_node(p->get_info());
44  NODE_COUNTER(q) = color;
45  GT::map_nodes(p, q);
46 
47  for (Node_Arc_Iterator<GT,SA> it(p); it.has_current(); it.next())
48  {
49  typename GT::Arc * a = it.get_current_arc();
50 
51  if (IS_ARC_VISITED(a, Depth_First))
52  continue;
53  ARC_BITS(a).set_bit(Depth_First, true);
54 
55  __dfp<GT,SA>(g, it.get_tgt_node(), blk, color);
56  }
57 }
58 
92  template <class GT, class SA> inline
94  DynDlist <GT> & blk_list,
96 {
97  g.reset_nodes();
98  g.reset_arcs();
99 
100  DynArray<typename GT::Node*> df; // arreglo de df por sufijo
101 
102  // recorre en profundidad y marca en sufijo los nodos
103  for (Node_Iterator<GT> it(g); it.has_current() and df.size() < g.vsize();
104  it.next())
105  __dfp<GT,SA>(g, it.get_current(), df);
106 
107  GT gi;
108  invert_digraph<GT,SA>(g, gi); // gi es el grafo invertido de g
109 
110  DynArray<GT*> array; // areglo de sub-grafos
111 
112  for (int i = df.size() - 1, color = 0; i >= 0; i--)
113  {
114  typename GT::Node * gp = df.access(i);
115  typename GT::Node * bp = mapped_node<GT>(gp);
116 
117  if (IS_NODE_VISITED(bp, Depth_First))
118  continue;
119 
120  GT & blk = blk_list.append(GT());
121  array[color] = &blk;
122 
123  __dfp<GT,SA>(gi, bp, blk, color++); // recorre el grafo inverso
124  // inserta los nodos en blk
125  I(NODE_COLOR(mapped_node<GT>(bp)) == color - 1);
126 
127  }
128 
129  for (Arc_Iterator<GT,SA> it(g); it.has_current(); it.next())
130  {
131  typename GT::Arc * a = it.get_current();
132  typename GT::Node * gs = g.get_src_node(a);
133  typename GT::Node * gt = g.get_tgt_node(a);
134 
135  typename GT::Node * bs = mapped_node<GT>(mapped_node<GT>(gs));
136  typename GT::Node * bt = mapped_node<GT>(mapped_node<GT>(gt));
137 
138  const long & color = NODE_COLOR(bs);
139 
140  if (color == NODE_COLOR(bt))
141  {
142  typename GT::Arc * ba = array.access(color)->insert_arc(bs, bt);
143  GT::map_arcs(a, ba);
144  }
145  else
146  arc_list.append(a);
147  }
148 }
149 
150 
151  template <class GT> inline
152 void kosaraju_connected_components(GT & g,
153  DynDlist <GT> & blk_list,
154  DynDlist<typename GT::Arc*> & arc_list)
155 {
156  kosaraju_connected_components<GT,Dft_Show_Arc<GT> >
157  (g, blk_list, arc_list);
158 }
159 
160 
161  /* Recorre el grafo invertido e inserta los nodos alcanzables en la
162  lista list. A cada nodo le coloca el color color
163 
164  */
165  template <class GT, class SA> inline static
166 void __dfp(GT & g, typename GT::Node * p, DynDlist<typename GT::Node *> & list)
167 {
168  if (IS_NODE_VISITED(p, Depth_First))
169  return;
170 
171  NODE_BITS(p).set_bit(Depth_First, true);
172 
173  list.append(mapped_node<GT>(p));
174 
175  for (Node_Arc_Iterator<GT,SA> it(p); it.has_current(); it.next())
176  {
177  typename GT::Arc * a = it.get_current_arc();
178 
179  if (IS_ARC_VISITED(a, Depth_First))
180  continue;
181  ARC_BITS(a).set_bit(Depth_First, true);
182 
183  __dfp<GT,SA>(g, it.get_tgt_node(), list);
184  }
185 }
186 
225  template <class GT, class SA> inline
228 {
229  g.reset_nodes();
230  g.reset_arcs();
231  DynArray<typename GT::Node*> df; // arreglo de df por sufijo
232 
233  // recorre en profundidad y marca en sufijo los nodos
234  for (Node_Iterator<GT> it(g); it.has_current() and df.size() < g.vsize();
235  it.next())
236  __dfp<GT,SA>(g, it.get_current(), df);
237 
238  GT gi;
239  invert_digraph<GT,SA>(g, gi); // gi es el grafo invertido de g
240 
241  for (int i = df.size() - 1; i >= 0; i--)
242  {
243  typename GT::Node * gp = df.access(i);
244  typename GT::Node * bp = mapped_node<GT>(gp);
245  if (IS_NODE_VISITED(bp, Depth_First))
246  continue;
247 
250 
251  __dfp<GT,SA>(gi, bp, blk);
252  }
253 }
254 
255 
256  template <class GT> inline
257 void kosaraju_connected_components(GT & g,
259 
260 {
261  kosaraju_connected_components<GT,Dft_Show_Arc<GT> > (g, list);
262 }
263 
292  template <class GT, class SA = Dft_Show_Arc<GT> >
294 {
295 public:
296 
305  void operator () (GT & g,
306  DynDlist <GT> & blk_list,
307  DynDlist<typename GT::Arc *> & arc_list)
308  {
309  kosaraju_connected_components<GT, SA> (g, blk_list, arc_list);
310  }
311 
320  {
321  kosaraju_connected_components<GT, SA> (g, list);
322  }
323 };
324 
325 } // end namespace Aleph
326 
327 # endif // KOSARAJU_H
Definition: kosaraju.H:293
size_t size() const
Retorna dimensión actual (más lejano índice escrito)
Definition: tpl_dynArray.H:523
Definition: tpl_dynDlist.H:26
Definition: tpl_graph.H:751
#define IS_NODE_VISITED(p, bit)
Definition: aleph-graph.H:242
#define NODE_COUNTER(p)
Definition: aleph-graph.H:226
#define IS_ARC_VISITED(p, bit)
Definition: aleph-graph.H:275
void kosaraju_connected_components(GT &g, DynDlist< DynDlist< typename GT::Node * > > &list)
Definition: kosaraju.H:226
void next()
Adelanta el iterador una posición.
Definition: filter_iterator.H:143
#define NODE_BITS(p)
Definition: aleph-graph.H:221
T & append()
Definition: tpl_dynArray.H:1115
Definition: tpl_graph.H:814
#define ARC_BITS(p)
Definition: aleph-graph.H:266
#define NODE_COLOR(p)
Definition: aleph-graph.H:232
T & access(const size_t i)
Definition: tpl_dynArray.H:793
void operator()(GT &g, DynDlist< GT > &blk_list, DynDlist< typename GT::Arc * > &arc_list)
Definition: kosaraju.H:305
Definition: tpl_graph.H:694
Definition: List.H:23
T & append(const T &item)
Definition: tpl_dynDlist.H:106

Leandro Rabindranath León