30 # include <tpl_dynListStack.H> 31 # include <tpl_dynSetTree.H> 33 # include <tpl_graph_utils.H> 34 # include <tpl_find_path.H> 75 noexcept(std::is_nothrow_move_assignable<SA>::value)
80 struct Init_Tarjan_Node
82 void operator () (
const GT & g,
typename GT::Node * p)
const noexcept
90 bool is_node_in_stack(
typename GT::Node * p)
const noexcept
95 void init_node_and_push_in_stack(
typename GT::Node * p)
97 assert(not is_node_in_stack(p));
101 NODE_BITS(p).set_bit(Aleph::Depth_First,
true);
102 df<GT>(p) = low<GT>(p) = df_count++;
105 typename GT::Node * pop_from_stack()
107 auto ret = stack.
pop();
108 NODE_BITS(ret).set_bit(Aleph::Min,
false);
113 void scc_by_blocks(
typename GT::Node * v)
115 init_node_and_push_in_stack(v);
118 for (Itor<GT, SA> it(v, sa); it.has_curr(); it.next_ne())
120 auto w = g_ptr->get_tgt_node(it.get_curr_ne());
124 low <GT> (v) = std::min(low <GT> (v), low <GT> (w));
126 else if (is_node_in_stack(w))
128 low <GT> (v) = std::min(low <GT> (v), df <GT> (w));
131 if (low <GT> (v) == df <GT> (v))
133 const auto & blk_idx = block_list_ptr->
size();
134 GT & blk = block_list_ptr->
append(GT());
138 auto p = pop_from_stack();
139 auto q = blk.insert_node(p->get_info());
150 void scc_by_lists(
typename GT::Node * v)
152 init_node_and_push_in_stack(v);
155 for (Itor<GT, SA> it(v, sa); it.has_curr(); it.next_ne())
157 auto w = g_ptr->get_tgt_node(it.get_curr_ne());
161 low <GT> (v) = std::min(low <GT> (v), low <GT> (w));
163 else if (is_node_in_stack(w))
165 low <GT> (v) = std::min(low <GT> (v), df <GT> (w));
168 if (low<GT>(v) == df<GT>(v))
173 auto p = pop_from_stack();
181 void scc_by_len(
typename GT::Node * v)
183 init_node_and_push_in_stack(v);
186 for (Itor<GT, SA> it(v, sa); it.has_curr(); it.next_ne())
188 auto w = g_ptr->get_tgt_node(it.get_curr_ne());
192 low <GT> (v) = std::min(low <GT> (v), low <GT> (w));
194 else if (is_node_in_stack(w))
196 low <GT> (v) = std::min(low <GT> (v), df <GT> (w));
199 if (low<GT>(v) == df<GT>(v))
204 auto p = pop_from_stack();
210 list_len_ptr->
append(count);
214 void init_tarjan(
const GT & g)
219 n = g.get_num_nodes();
220 g_ptr = &
const_cast<GT&
>(g);
224 bool has_cycle(
typename GT::Node * v)
226 init_node_and_push_in_stack(v);
229 for (Itor <GT, SA> it(v, sa); it.has_curr(); it.next_ne())
231 auto w = g_ptr->get_tgt_node(it.get_curr_ne());
237 low<GT>(v) = std::min(low<GT>(v), low<GT>(w));
239 else if (is_node_in_stack(w))
241 low<GT>(v) = std::min(low<GT>(v), df<GT>(w));
244 if (low<GT>(v) == df<GT>(v))
248 if (pop_from_stack() == v)
260 build_path(
const GT & block,
264 auto a = block.get_first_arc();
265 auto start = block.get_tgt_node(a);
266 auto end = block.get_src_node(a);
267 assert(start != end);
270 assert(not aux_path.is_empty());
284 bool build_cycle(
typename GT::Node * v)
286 init_node_and_push_in_stack(v);
289 for (Itor <GT, SA> it(v, sa); it.has_curr(); it.next_ne())
291 auto w = g_ptr->get_tgt_node(it.get_curr_ne());
297 low<GT>(v) = std::min(low<GT>(v), low<GT>(w));
299 else if (is_node_in_stack(w))
301 low<GT>(v) = std::min(low<GT>(v), df<GT>(w));
304 if (low<GT>(v) == df<GT>(v))
314 auto p = pop_from_stack();
315 auto q = blk.insert_node();
323 if (blk.get_num_nodes() == 1)
327 for (
typename GT::Node_Iterator j(blk); j.has_curr(); j.next_ne())
329 auto bsrc = j.get_curr_ne();
330 auto gsrc = table.
find(bsrc);
333 for (Itor <GT, SA> k(gsrc, sa); k.has_curr(); k.next_ne())
335 auto ga = k.get_curr_ne();
336 auto gtgt = g_ptr->get_tgt_node(ga);
337 auto ptr = table.
search(gtgt);
341 auto ta = blk.insert_arc(bsrc, ptr->second);
346 build_path(blk, table);
356 bool is_connected(
typename GT::Node * v)
358 init_node_and_push_in_stack(v);
361 for (Itor <GT, SA> it(v, sa); it.has_curr(); it.next_ne())
363 auto w = g_ptr->get_tgt_node(it.get_curr_ne());
366 if (not is_connected(w))
369 low <GT> (v) = std::min(low <GT> (v), low <GT> (w));
371 else if (is_node_in_stack(w))
372 low <GT> (v) = std::min(low <GT> (v), df <GT> (w));
375 if (low<GT>(v) == df<GT>(v))
377 while (pop_from_stack() != v);
420 block_list_ptr = &blk_list;
422 for (
typename GT::Node_Iterator it(g); df_count < n; it.next_ne())
424 auto v = it.get_curr_ne();
434 GT & blk = i.get_curr_ne();
435 for (
typename GT::Node_Iterator j(blk); j.has_curr(); j.next_ne())
437 auto bsrc = j.get_curr_ne();
438 auto gsrc = mapped_node<GT>(bsrc);
441 for (Itor<GT, SA> k(gsrc, sa); k.has_curr(); k.next_ne())
443 auto ga = k.get_curr_ne();
444 auto gtgt = g_ptr->get_tgt_node(ga);
452 auto btgt = mapped_node<GT>(gtgt);
453 auto ba = blk.insert_arc(bsrc, btgt);
498 list_list_ptr = &blks;
499 for (
typename GT::Node_Iterator it(g); df_count < n; it.next_ne())
501 auto v = it.get_curr_ne();
539 list_len_ptr = &blks;
540 for (
typename GT::Node_Iterator it(g); df_count < n; it.next_ne())
542 auto v = it.get_curr_ne();
579 GT & curr = it.get_curr_ne();
580 GT & block = blk_list.
append(GT());
586 arc_list.
append(it.get_curr_ne());
597 it.has_curr(); it.next_ne())
601 auto & blk = it.get_curr_ne();
602 while (not blk.is_empty())
603 tgt_list.append(blk.remove_first());
611 for (
typename GT::Node_Iterator it(g); df_count < n; it.next_ne())
613 auto v = it.get_curr_ne();
625 return not has_cycle(g);
628 bool compute_cycle(
const GT & g,
Path<GT> & path)
634 for (
typename GT::Node_Iterator it(g); df_count < n; it.next_ne())
636 auto v = it.get_curr_ne();
646 bool compute_cycle(
const GT & g,
typename GT::Node * src,
Path<GT> & path)
651 return build_cycle(src);
657 for (
typename GT::Node_Iterator it(g); df_count < n; it.next_ne())
659 auto v = it.get_curr_ne();
661 if (not is_connected(v))
701 noexcept(std::is_nothrow_move_assignable<SA>::value)
705 noexcept(std::is_nothrow_copy_assignable<SA>::value)
720 return tarjan.compute_cycle(g, path);
size_t size() const noexcept
Definition: htlist.H:1240
bool has_curr() const noexcept
Return true if the iterator has current item.
Definition: dlink.H:658
void empty() noexcept
empty the list
Definition: htlist.H:1598
Node * get_first_node() const
Definition: tpl_graph.H:3069
Pair * insert(const Key &key, const Type &data)
Definition: tpl_dynMapTree.H:112
#define NODE_COOKIE(p)
Definition: aleph-graph.H:333
Definition: tpl_dynMapTree.H:328
bool test_connectivity(const GT &g)
Definition: tpl_graph_utils.H:565
Definition: tpl_dynDlist.H:51
Definition: tpl_graph.H:2493
#define IS_NODE_VISITED(p, bit)
Definition: aleph-graph.H:327
T & push(const T &item)
Definition: htlist.H:1432
bool is_empty() const noexcept
Definition: htlist.H:466
bool has_curr() const noexcept
Definition: htlist.H:1071
#define NODE_COUNTER(p)
Definition: aleph-graph.H:311
void map_arcs(typename GTS::Arc *p, typename GTT::Arc *q) noexcept
Definition: tpl_graph.H:3445
bool has_cycle(const GT &g)
Retorna true si el digrafo g contiene al menos un ciclo.
Definition: Tarjan.H:608
Definition: tpl_graph.H:53
void connected_components(const GT &g, DynList< DynList< typename GT::Node *>> &blks)
Definition: Tarjan.H:494
void map_nodes(typename GTS::Node *p, typename GTT::Node *q) noexcept
Definition: tpl_graph.H:3419
Definition: tpl_find_path.H:411
Definition: tpl_graph.H:1063
void append_directed(Node *p)
Definition: tpl_graph.H:2880
bool is_dag(const GT &g)
Retorna true si el grafo dirigido es acÃclico.
Definition: Tarjan.H:623
Pair * search(const Key &key) const noexcept
Definition: tpl_dynMapTree.H:214
Definition: tpl_graph.H:1796
#define NODE_BITS(p)
Definition: aleph-graph.H:305
void connected_components(const GT &g, DynList< size_t > &blks)
Definition: Tarjan.H:536
T pop()
Definition: htlist.H:1543
void set_graph(const GT &__g, Node *start_node=nullptr)
Definition: tpl_graph.H:2745
void connected_components(const GT &g, DynList< GT > &blk_list, DynList< typename GT::Arc *> &arc_list)
Definition: Tarjan.H:415
bool is_empty() const noexcept
Return true if the path is empty.
Definition: tpl_graph.H:2758
Definition: htlist.H:1622
void operator()(const GT &g, DynList< GT > &blk_list, DynList< typename GT::Arc *> &arc_list)
Definition: Tarjan.H:549
void empty()
Clean the path: all the nodes and arc are removed.
Definition: tpl_graph.H:2761
T & append(const T &item)
Definition: htlist.H:1471
Definition: tpl_graph.H:3135
T & append(const T &item)
Definition: tpl_dynDlist.H:149
Type & find(const Key &key)
Definition: tpl_dynMapTree.H:242