Aleph-w  1.9
General library for algorithms and data structures
tpl_test_cycle.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_TEST_CYCLE_H
28 # define TPL_TEST_CYCLE_H
29 
30 # include <tpl_graph.H>
31 
32 namespace Aleph {
33 
34 
45  template <class GT, class SA = Dft_Show_Arc<GT>>
47 {
48  typename GT::Node * src = nullptr;
49  SA sa;
50 
51  bool test_cycle(typename GT::Node * curr)
52  {
53  if (src == curr)
54  return true; // ciclo detectado!
55 
56  if (IS_NODE_VISITED(curr, Test_Cycle))
57  return false;
58 
59  NODE_BITS(curr).set_bit(Test_Cycle, true); // marque nodo
60 
61  // buscar caminos desde current_node a ver si llega a src_node
62  for (Node_Arc_Iterator<GT, SA> it(curr, sa); it.has_curr(); it.next_ne())
63  {
64  typename GT::Arc * arc = it.get_current_arc_ne();
65  if (IS_ARC_VISITED(arc, Test_Cycle))
66  continue;
67 
68  ARC_BITS(arc).set_bit(Test_Cycle, true); // marque arco
69 
70  if (test_cycle(it.get_tgt_node()))
71  return true; // ciclo encontrado desde el arco actual
72  }
73 
74  // En este punto se han explorado caminos desde curr_node
75  // sin encontrar src_node ==> no existe ciclo por curr_node
76  return false;
77  }
78 
79  bool test_cycle(GT & g, typename GT::Node * s)
80  {
81  src = s;
82 
83  g.reset_bit_nodes(Test_Cycle); // reiniciar Test_Cycle para nodos
84  g.reset_bit_arcs(Test_Cycle); // reiniciar Test_Cycle para arcos
85 
86  // explorar recursivamente por arcos adyacentes a src_node
87  for (Node_Arc_Iterator<GT, SA> it(src, sa); it.has_curr(); it.next_ne())
88  {
89  typename GT::Arc * arc = it.get_current_arc_ne();
90  if (IS_ARC_VISITED(arc, Test_Cycle))
91  continue;
92 
93  ARC_BITS(arc).set_bit(Test_Cycle, true); // pintar arco
94 
95  if (test_cycle(it.get_tgt_node()))
96  return true; // ciclo detectado
97  }
98 
99  // Se han explorado todos los caminos desde src_node
100  // sin encontrar de nuevo a src_node ==> no hay ciclo
101  return false;
102  }
103 
104 public:
105 
106  Test_For_Cycle(SA __sa = SA()) : sa(__sa) { /* empty */ }
107 
117  bool operator () (GT & g, typename GT::Node * src)
118  {
119  return this->test_cycle(g, src);
120  }
121 };
122 
123 } // end namespace Aleph
124 
125 
126 # endif // TPL_TEST_CYCLE_H
#define IS_NODE_VISITED(p, bit)
Definition: aleph-graph.H:327
#define IS_ARC_VISITED(p, bit)
Definition: aleph-graph.H:360
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_test_cycle.H:46
Definition: tpl_graph.H:1177
bool operator()(GT &g, typename GT::Node *src)
Definition: tpl_test_cycle.H:117

Leandro Rabindranath León