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 <tpl_graph.H>
43# include <ah-errors.H>
44
45namespace Aleph {
46
106template <class GT, class SA = Dft_Show_Arc<GT>>
108{
109 mutable typename GT::Node * src = nullptr;
111
112 // Recursive DFS helper to detect if a path from curr returns to src
113 bool test_cycle(typename GT::Node * curr) const
114 {
115 // Base case: found a path back to source -> cycle detected
116 if (src == curr)
117 return true;
118
119 // Already visited this node in current DFS -> no cycle via this path
120 if (IS_NODE_VISITED(curr, Test_Cycle))
121 return false;
122
123 // Mark current node as visited
124 NODE_BITS(curr).set_bit(Test_Cycle, true);
125
126 // Explore all outgoing arcs from current node
127 for (Node_Arc_Iterator<GT, SA> it(curr, sa); it.has_curr(); it.next_ne())
128 {
129 typename GT::Arc * arc = it.get_current_arc_ne();
130
131 // Skip already-visited arcs to avoid infinite loops
132 if (IS_ARC_VISITED(arc, Test_Cycle))
133 continue;
134
135 // Mark arc as visited
136 ARC_BITS(arc).set_bit(Test_Cycle, true);
137
138 // Recursively check if target node leads to a cycle
139 if (test_cycle(it.get_tgt_node()))
140 return true;
141 }
142
143 // All paths from curr explored without finding src -> no cycle
144 return false;
145 }
146
147 // Main algorithm entry point
148 bool test_cycle(const GT & g, typename GT::Node * s) const
149 {
150 ah_invalid_argument_if(s == nullptr)
151 << "Test_For_Cycle: source node cannot be null";
152
153 src = s;
154
155 // Reset control bits for a fresh traversal
158
159 // Explore all arcs adjacent to source node
160 for (Node_Arc_Iterator<GT, SA> it(src, sa); it.has_curr(); it.next_ne())
161 {
162 typename GT::Arc * arc = it.get_current_arc_ne();
163
164 // Skip already-visited arcs (shouldn't happen in first iteration)
165 if (IS_ARC_VISITED(arc, Test_Cycle))
166 continue;
167
168 // Mark arc as visited
169 ARC_BITS(arc).set_bit(Test_Cycle, true);
170
171 // Check if target node leads back to source
172 if (test_cycle(it.get_tgt_node()))
173 return true;
174 }
175
176 // All paths explored without finding a cycle
177 return false;
178 }
179
180public:
181
187 Test_For_Cycle(SA arc_filter = SA()) : sa(arc_filter) { /* empty */ }
188
212 bool operator () (const GT & g, typename GT::Node * src_node) const
213 {
214 return this->test_cycle(g, src_node);
215 }
216};
217
218} // end namespace Aleph
219
220
221# 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:639
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:1040
void reset_bit_arcs(int bit) const noexcept
Reset bit to zero for all the arcs of graph.
Definition graph-dry.H:1046
#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
DynList< T > maps(const C &c, Op op)
Classic map operation.
Arc of graph implemented with double-linked adjacency lists.
Definition tpl_graph.H:222
Filtered iterator of adjacent arcs of a node.
Definition tpl_graph.H:1119
Generic graph and digraph implementations.