4 # include <tpl_dynListStack.H>
5 # include <tpl_dynSetTree.H>
7 # include <tpl_graph_utils.H>
8 # include <tpl_find_path.H>
23 template <
class GT,
class SA = Dft_Show_Arc<GT>>
51 struct Init_Tarjan_Node
61 bool is_node_in_stack(
typename GT::Node * p)
66 void init_node_and_push_in_stack(
typename GT::Node * p)
68 I(not is_node_in_stack(p));
72 NODE_BITS(p).set_bit(Aleph::Depth_First,
true);
73 df<GT>(p) = low<GT>(p) = df_count++;
76 typename GT::Node * pop_from_stack()
78 typename GT::Node * ret =
stack.
pop();
79 NODE_BITS(ret).set_bit(Aleph::Min,
false);
84 void scc_by_blocks(
typename GT::Node * v)
86 init_node_and_push_in_stack(v);
91 typename GT::Node * w = it.get_tgt_node();
95 low <GT> (v) = std::min(low <GT> (v), low <GT> (w));
97 else if (is_node_in_stack(w))
99 low <GT> (v) = std::min(low <GT> (v), df <GT> (w));
102 if (low <GT> (v) == df <GT> (v))
104 const size_t & blk_idx = block_list_ptr->size();
105 GT & blk = block_list_ptr->
append(GT());
109 typename GT::Node * p = pop_from_stack();
110 typename GT::Node * q = blk.insert_node(p->get_info());
120 void scc_by_lists(
typename GT::Node * v)
122 init_node_and_push_in_stack(v);
127 typename GT::Node * w = it.get_tgt_node();
131 low <GT> (v) = std::min(low <GT> (v), low <GT> (w));
133 else if (is_node_in_stack(w))
135 low <GT> (v) = std::min(low <GT> (v), df <GT> (w));
138 if (low<GT>(v) == df<GT>(v))
145 typename GT::Node * p = pop_from_stack();
154 void scc_by_len(
typename GT::Node * v)
156 init_node_and_push_in_stack(v);
161 typename GT::Node * w = it.get_tgt_node();
165 low <GT> (v) = std::min(low <GT> (v), low <GT> (w));
167 else if (is_node_in_stack(w))
169 low <GT> (v) = std::min(low <GT> (v), df <GT> (w));
172 if (low<GT>(v) == df<GT>(v))
178 typename GT::Node * p = pop_from_stack();
184 list_len_ptr->
append(count);
188 void init_tarjan(GT & g)
190 if (not g.is_digraph())
191 throw std::domain_error(
"g is not a digraph");
199 n = g.get_num_nodes();
203 bool has_cycle(
typename GT::Node * v)
205 init_node_and_push_in_stack(v);
210 typename GT::Node * w = it.get_tgt_node();
216 low<GT>(v) = std::min(low<GT>(v), low<GT>(w));
218 else if (is_node_in_stack(w))
220 low<GT>(v) = std::min(low<GT>(v), df<GT>(w));
223 if (low<GT>(v) == df<GT>(v))
227 if (pop_from_stack() == v)
239 build_path(GT & block,
243 typename GT::Arc * a = block.get_first_arc();
247 block.get_src_node(a), aux_path);
249 path_ptr->clear_path();
251 path_ptr->append(table.
find(i.get_current_node()));
253 path_ptr->append(table.
find(block.get_tgt_node(a)));
258 bool build_cycle(
typename GT::Node * v)
260 init_node_and_push_in_stack(v);
265 typename GT::Node * w = it.get_tgt_node();
271 low<GT>(v) = std::min(low<GT>(v), low<GT>(w));
273 else if (is_node_in_stack(w))
275 low<GT>(v) = std::min(low<GT>(v), df<GT>(w));
278 if (low<GT>(v) == df<GT>(v))
288 typename GT::Node * p = pop_from_stack();
289 typename GT::Node * q = blk.insert_node(p->get_info());
296 if (blk.get_num_nodes() == 1)
300 for (
typename GT::Node_Iterator j(blk); j.has_curr(); j.next())
302 typename GT::Node * bsrc = j.get_curr();
303 typename GT::Node * gsrc = table.
find(bsrc);
308 typename GT::Node * gtgt = k.get_tgt_node();
309 typename GT::Node ** btgt_ptr = table.
test(gtgt);
310 if (btgt_ptr == NULL)
313 typename GT::Arc * ga = k.get_current_arc();
314 blk.insert_arc(bsrc, *btgt_ptr, ga->get_info());
318 build_path(blk, table);
326 bool is_connected(
typename GT::Node * v)
328 init_node_and_push_in_stack(v);
333 typename GT::Node * w = it.get_tgt_node();
336 if (not is_connected(w))
339 low <GT> (v) = std::min(low <GT> (v), low <GT> (w));
341 else if (is_node_in_stack(w))
342 low <GT> (v) = std::min(low <GT> (v), df <GT> (w));
345 if (low<GT>(v) == df<GT>(v))
347 while (pop_from_stack() != v);
349 return stack.is_empty();
390 block_list_ptr = &blk_list;
392 for (
typename GT::Node_Iterator it(g); df_count < n; it.next())
394 typename GT::Node * v = it.get_curr();
404 GT & blk = i.get_curr();
405 for (
typename GT::Node_Iterator j(blk); j.has_curr(); j.next())
407 typename GT::Node * bsrc = j.get_curr();
408 typename GT::Node * gsrc = mapped_node<GT>(bsrc);
413 typename GT::Node * gtgt = k.get_tgt_node();
414 typename GT::Arc * ga = k.get_current_arc();
422 typename GT::Node * btgt = mapped_node<GT>(gtgt);
423 typename GT::Arc * ba =
424 blk.insert_arc(bsrc, btgt, ga->get_info());
426 GT::map_arcs(ga, ba);
470 list_list_ptr = &blks;
472 for (
typename GT::Node_Iterator it(g); df_count < n; it.next())
474 typename GT::Node * v = it.get_curr();
506 list_len_ptr = &blks;
508 for (
typename GT::Node_Iterator it(g); df_count < n; it.next())
510 typename GT::Node * v = it.get_curr();
542 GT & curr = it.get_curr();
543 GT & block = blk_list.
append(GT());
548 it.has_curr(); it.next())
549 arc_list.
append(it.get_curr());
560 it.has_curr(); it.next())
576 for (
typename GT::Node_Iterator it(g); df_count < n; it.next())
578 typename GT::Node * v = it.get_curr();
590 return not has_cycle(g);
593 bool compute_cycle(GT & g,
Path<GT> & path)
597 path_ptr->set_graph(g);
601 typename GT::Node * v = it.get_curr();
610 bool test_connectivity(GT & g)
614 for (
typename GT::Node_Iterator it(g); df_count < n; it.next())
616 typename GT::Node * v = it.get_curr();
618 if (not is_connected(v))
648 template <
class GT,
class SA = Dft_Show_Arc<GT>>
671 return tarjan.compute_cycle(g, path);
void connected_components(GT &g, DynList< DynList< typename GT::Node * >> &blks)
Definition: Tarjan.H:465
Type * test(const Key &key)
Definition: tpl_dynMapTree.H:191
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Definition: ahAlgo.H:127
T remove_first()
Definition: htlist.H:719
bool operator()(GT &g, Path< GT > &path) const
Definition: Tarjan.H:667
#define NODE_COOKIE(p)
Definition: aleph-graph.H:248
Definition: tpl_dynMapTree.H:260
Definition: tpl_dynDlist.H:26
Definition: tpl_graph.H:1389
void operator()(GT &g, DynList< GT > &blk_list, DynList< typename GT::Arc * > &arc_list)
Definition: Tarjan.H:517
#define IS_NODE_VISITED(p, bit)
Definition: aleph-graph.H:242
bool is_empty() const
Retorna true si la lista está vacía.
Definition: htlist.H:248
bool is_dag(GT &g)
Retorna true si el grafo dirigido es acíclico.
Definition: Tarjan.H:588
#define NODE_COUNTER(p)
Definition: aleph-graph.H:226
void connected_components(GT &g, DynList< GT > &blk_list, DynList< typename GT::Arc * > &arc_list)
Definition: Tarjan.H:385
bool empty() const
Retorna true si la pila está vacía.
Definition: Stack.H:42
Definition: tpl_graph.H:1186
Definition: tpl_graph.H:26
Definition: tpl_find_path.H:33
void next()
Adelanta el iterador una posición.
Definition: filter_iterator.H:143
#define NODE_BITS(p)
Definition: aleph-graph.H:221
Definition: tpl_graph.H:814
T pop()
Definition: tpl_dynListStack.H:122
T & push(const T &item)
Definition: tpl_dynListStack.H:93
void connected_components(GT &g, DynList< size_t > &blks)
Definition: Tarjan.H:502
T & append(const T &item)
Inserta un item como último elemento.
Definition: htlist.H:685
bool has_cycle(GT &g)
Retorna true si el digrafo g contiene al menos un ciclo.
Definition: Tarjan.H:572
Key * insert(const Key &key, const Type &data)
Definition: tpl_dynMapTree.H:74
Definition: tpl_graph.H:1868
T & append(const T &item)
Definition: tpl_dynDlist.H:106
Type & find(const Key &key)
Definition: tpl_dynMapTree.H:223