Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_test_cycle.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
39# ifndef TPL_TEST_CYCLE_H
40# define TPL_TEST_CYCLE_H
41
42# include <ah-graph-concepts.H>
43
44# include <tpl_graph.H>
45# include <ah-errors.H>
46
47namespace Aleph {
48
108template <AlephGraph GT, ArcFilter<GT> SA = Dft_Show_Arc<GT>>
110{
111 mutable typename GT::Node * src = nullptr;
112 SA sa;
113
114 // Recursive DFS helper to detect if a path from curr returns to src
115 bool test_cycle(typename GT::Node * curr) const
116 {
117 // Base case: found a path back to source -> cycle detected
118 if (src == curr)
119 return true;
120
121 // Already visited this node in current DFS -> no cycle via this path
122 if (IS_NODE_VISITED(curr, Test_Cycle))
123 return false;
124
125 // Mark current node as visited
126 NODE_BITS(curr).set_bit(Test_Cycle, true);
127
128 // Explore all outgoing arcs from current node
129 for (Node_Arc_Iterator<GT, SA> it(curr, sa); it.has_curr(); it.next_ne())
130 {
131 typename GT::Arc * arc = it.get_current_arc_ne();
132
133 // Skip already-visited arcs to avoid infinite loops
134 if (IS_ARC_VISITED(arc, Test_Cycle))
135 continue;
136
137 // Mark arc as visited
138 ARC_BITS(arc).set_bit(Test_Cycle, true);
139
140 // Recursively check if target node leads to a cycle
141 if (test_cycle(it.get_tgt_node()))
142 return true;
143 }
144
145 // All paths from curr explored without finding src -> no cycle
146 return false;
147 }
148
149 // Main algorithm entry point
150 bool test_cycle(const GT & g, typename GT::Node * s) const
151 {
152 ah_invalid_argument_if(s == nullptr)
153 << "Test_For_Cycle: source node cannot be null";
154
155 src = s;
156
157 // Reset control bits for a fresh traversal
160
161 // Explore all arcs adjacent to source node
162 for (Node_Arc_Iterator<GT, SA> it(src, sa); it.has_curr(); it.next_ne())
163 {
164 typename GT::Arc * arc = it.get_current_arc_ne();
165
166 // Skip already-visited arcs (shouldn't happen in first iteration)
167 if (IS_ARC_VISITED(arc, Test_Cycle))
168 continue;
169
170 // Mark arc as visited
171 ARC_BITS(arc).set_bit(Test_Cycle, true);
172
173 // Check if target node leads back to source
174 if (test_cycle(it.get_tgt_node()))
175 return true;
176 }
177
178 // All paths explored without finding a cycle
179 return false;
180 }
181
182public:
183
189 Test_For_Cycle(SA arc_filter = SA()) : sa(arc_filter) { /* empty */ }
190
214 bool operator () (const GT & g, typename GT::Node * src_node) const
215 {
216 return this->test_cycle(g, src_node);
217 }
218};
219
220} // end namespace Aleph
221
222
223# endif // TPL_TEST_CYCLE_H
Exception handling system with formatted messages for Aleph-w.
#define ah_invalid_argument_if(C)
Throws std::invalid_argument if condition holds.
Definition ah-errors.H:644
C++20 concepts for the protocol shared by graph algorithms.
void next_ne() noexcept
Advances the iterator to the next filtered element (noexcept version).
Test whether a cycle is reachable from a given node.
bool test_cycle(typename GT::Node *curr) const
bool test_cycle(const GT &g, typename GT::Node *s) const
Test_For_Cycle(SA arc_filter=SA())
Construct a cycle tester with optional arc filter.
bool operator()(const GT &g, typename GT::Node *src_node) const
Test whether a cycle is reachable from the given source node.
void reset_bit_nodes(int bit) const noexcept
Reset bit to zero for all the nodes of graph.
Definition graph-dry.H:1088
void reset_bit_arcs(int bit) const noexcept
Reset bit to zero for all the arcs of graph.
Definition graph-dry.H:1094
#define IS_NODE_VISITED(p, bit)
Determine whether the control bit is set or not to one.
#define ARC_BITS(p)
Return the control bits of arc p.
#define IS_ARC_VISITED(p, bit)
Determine whether the bit field is or not set to one.
#define NODE_BITS(p)
Get the control bits of a node.
@ Test_Cycle
Definition aleph-graph.H:75
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
Filtered iterator of adjacent arcs of a node.
Definition tpl_graph.H:1120
Generic graph and digraph implementations.