Aleph-w  1.5a.2
Biblioteca general de algoritmos y estructuras de datos
 Todo Clases Archivos Funciones Variables 'typedefs' Enumeraciones Amigas Grupos Páginas
tpl_spanning_tree.H
1 # ifndef TPL_SPANNING_TREE_H
2 # define TPL_SPANNING_TREE_H
3 
4 namespace Aleph {
5 
6 
25  template <class GT, class SA = Dft_Show_Arc<GT> >
27 {
28  SA & sa;
29  GT * gptr;
30  GT * tptr;
31 
32  bool build_tree(typename GT::Node * gnode, typename GT::Arc * garc,
33  typename GT::Node * tnode)
34  {
35  NODE_BITS(gnode).set_bit(Spanning_Tree, true); // marcar nodo
36  ARC_BITS(garc).set_bit(Spanning_Tree, true); // marcar arco
37 
38  typename GT::Node * tree_tgt_node = tptr->insert_node(gnode->get_info());
39  GT::map_nodes(gnode, tree_tgt_node);
40 
41  typename GT::Arc * tarc =
42  tptr->insert_arc(tnode, tree_tgt_node, garc->get_info());
43  GT::map_arcs(garc, tarc);
44 
45  tnode = tree_tgt_node;
46  if (tptr->get_num_nodes() == gptr->get_num_nodes()) // ¿grafo abarcado?
47  return true; // tree ya contiene el árbol abarcador
48 
49  I(tptr->get_num_nodes() > tptr->get_num_arcs()); // debe ser acíclico
50 
51  for (Node_Arc_Iterator<GT, SA> i(gnode, sa);
52  i.has_curr() and tptr->get_num_nodes() < gptr->get_num_nodes();
53  i.next())
54  {
55  typename GT::Arc * arc = i.get_current_arc();
56  if (IS_ARC_VISITED(arc, Spanning_Tree))
57  continue;
58 
59  typename GT::Node * arc_tgt_node = i.get_tgt_node();
60  if (IS_NODE_VISITED(arc_tgt_node, Spanning_Tree))
61  continue; // destino ya visitado desde otro arco
62 
63  if (build_tree(arc_tgt_node, arc, tnode))
64  return false;
65  }
66 
67  return false;
68  }
69 
70  bool build_tree(GT & g, typename GT::Node * gnode, GT & tree)
71  {
72  gptr = &g;
73  tptr = &tree;
74 
75  gptr->reset_nodes();
76  gptr->reset_arcs();
77 
78  clear_graph(*tptr); // asegurar que árbol destino esté vacío
79 
80  NODE_BITS(gnode).set_bit(Spanning_Tree, true); // marcar gnode
81 
82  typename GT::Node * tnode = tree.insert_node(gnode->get_info());
83  GT::map_nodes(gnode, tnode);
84 
85  for (Node_Arc_Iterator<GT, SA> i(gnode, sa);
86  i.has_curr() and tptr->get_num_nodes() < gptr->get_num_nodes();
87  i.next())
88  {
89  typename GT::Arc * arc = i.get_current_arc();
90  if (IS_ARC_VISITED(arc, Spanning_Tree))
91  continue;
92 
93  typename GT::Node * arc_tgt_node = i.get_tgt_node();
94  if (IS_NODE_VISITED(arc_tgt_node, Spanning_Tree))
95  continue; // destino ya visitado desde otro arco
96 
97  if (build_tree(arc_tgt_node, arc, tnode))
98  return false;
99  }
100 
101  return true;
102  }
103 
104 public:
105 
106  Find_Depth_First_Spanning_Tree(SA && __sa = SA()) : sa(__sa) { /* empty */ }
107 
108  Find_Depth_First_Spanning_Tree(SA & __sa) : sa(__sa) { /* empty */ }
109 
130  typename GT::Node * operator () (GT & g, GT & tree)
131  {
132  typename GT::Node * start = g.get_first_node();
133  if (not build_tree(g, start, tree))
134  return NULL;
135 
136  return start;
137  }
138 
163  typename GT::Node * operator () (GT & g, typename GT::Node * gnode, GT & tree)
164  {
165  this->build_tree(g, gnode, tree);
166  return (typename GT::Node *) NODE_COOKIE(gnode);
167  }
168 };
169 
170 
171 
194  template <class GT, class SA = Dft_Show_Arc<GT> >
196 {
197  SA & sa;
198 
199  void build_tree(GT & g, typename GT::Node * gp, GT & tree)
200  {
201  g.reset_bit_nodes(Spanning_Tree);
202  g.reset_bit_arcs(Spanning_Tree);
203 
204  clear_graph(tree);
205 
206  unique_ptr<typename GT::Node> tp_auto(new typename GT::Node(gp));
207  tree.insert_node(tp_auto.get());
208  GT::map_nodes(gp, tp_auto.release());
209 
210  DynListQueue<typename GT::Arc*> q; // insertar en cola arcos gp
211  for (Node_Arc_Iterator<GT, SA> i(gp, sa); i.has_curr(); i.next())
212  q.put(i.get_current_arc());
213 
214  NODE_BITS(gp).set_bit(Spanning_Tree, true);
215 
216  while (not q.is_empty())
217  {
218  typename GT::Arc * garc = q.get();
219  ARC_BITS(garc).set_bit(Spanning_Tree, true);
220  typename GT::Node * gsrc = g.get_src_node(garc);
221  typename GT::Node * gtgt = g.get_tgt_node(garc);
222 
223  if (IS_NODE_VISITED(gsrc, Spanning_Tree) and
224  IS_NODE_VISITED(gtgt, Spanning_Tree))
225  continue; // los dos nodos de garc ya fueron visitados
226 
227  if (IS_NODE_VISITED(gtgt, Spanning_Tree)) // ¿gtgt visitado?
228  std::swap(gsrc, gtgt); // sí, intercámbielo con gsrc
229 
230  typename GT::Node * tsrc = mapped_node<GT>(gsrc);
231  NODE_BITS(gtgt).set_bit(Spanning_Tree, true); // gtgt visitado
232 
233  // crear copia de gtgt, insertarlo en tree y mapearlo
234  unique_ptr<typename GT::Node> ttgt_auto(new typename GT::Node(gtgt));
235  tree.insert_node(ttgt_auto.get());
236  typename GT::Node * ttgt = ttgt_auto.release();
237  GT::map_nodes(gtgt, ttgt);
238 
239  // insertar nuevo arco en tree y mapearlo
240  typename GT::Arc * tarc = tree.insert_arc(tsrc, ttgt, garc->get_info());
241  GT::map_arcs(garc, tarc);
242  if (tree.get_num_nodes() == g.get_num_nodes()) // ¿abarca a g?
243  break;
244 
245  // insertar en cola arcos de gtgt
246  for (Node_Arc_Iterator<GT, SA> i(gtgt, sa); i.has_curr(); i.next())
247  {
248  typename GT::Arc * current_arc = i.get_current_arc();
249  if (IS_ARC_VISITED(current_arc, Spanning_Tree))
250  continue;
251 
252  // revise nodos de arcos para ver si han sido visitados
253  if (IS_NODE_VISITED(g.get_src_node(current_arc), Spanning_Tree) and
254  IS_NODE_VISITED(g.get_tgt_node(current_arc), Spanning_Tree))
255  continue; // nodos ya visitados ==> no meter arco
256  q.put(current_arc);
257  }
258  }
259  }
260 
261 public:
262 
263  Find_Breadth_First_Spanning_Tree(SA && __sa = SA()) : sa(__sa) { /* empty */ }
264 
265  Find_Breadth_First_Spanning_Tree(SA & __sa) : sa(__sa) { /* empty */ }
266 
286  void operator () (GT & g, typename GT::Node * gnode, GT & tree)
287  {
288  find_breadth_first_spanning_tree <GT, SA> (g, gnode, tree);
289  }
290  };
291 
292 
301  template <class GT>
303 {
304 public:
305 
319  void operator () (GT & g, GT & tree,
322  const bool with_map = false) const
323  {
324  build_spanning_tree(g, tree, pred, arcs, with_map);
325  }
326 };
327 
328 
329 } // end namespace Aleph
330 
331 # endif // TPL_SPANNING_TREE_H
void operator()(GT &g, typename GT::Node *gnode, GT &tree)
Definition: tpl_spanning_tree.H:286
GT::Node * operator()(GT &g, GT &tree)
Definition: tpl_spanning_tree.H:130
#define NODE_COOKIE(p)
Definition: aleph-graph.H:248
#define IS_NODE_VISITED(p, bit)
Definition: aleph-graph.H:242
Definition: tpl_dynListQueue.H:22
void operator()(GT &g, GT &tree, DynArray< typename GT::Node > *pred, DynArray< typename GT::Arc > *arcs, const bool with_map=false) const
Definition: tpl_spanning_tree.H:319
void clear_graph(GT &g)
Definition: tpl_graph.H:2486
#define IS_ARC_VISITED(p, bit)
Definition: aleph-graph.H:275
void build_spanning_tree(GT &g, GT &tree, DynArray< typename GT::Arc > *arcs, const bool with_map=false)
Definition: tpl_graph_utils.H:1536
void next()
Adelanta el iterador una posición.
Definition: filter_iterator.H:143
Definition: tpl_spanning_tree.H:26
#define NODE_BITS(p)
Definition: aleph-graph.H:221
#define ARC_BITS(p)
Definition: aleph-graph.H:266
Definition: tpl_dynArray.H:70
Definition: tpl_spanning_tree.H:302
Definition: tpl_spanning_tree.H:195
Definition: tpl_graph.H:694
T & put(const T &data)
Definition: tpl_dynListQueue.H:86

Leandro Rabindranath León