Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_find_path.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
52# ifndef TPL_FIND_PATH_H
53# define TPL_FIND_PATH_H
54
55# include <ah-graph-concepts.H>
56
57# include <tpl_dynListStack.H>
58# include <tpl_dynListQueue.H>
59# include <tpl_graph_utils.H>
60# include <ah-errors.H>
61
62namespace Aleph
63{
64 template <class GT>
66 {
67 bool operator ()(typename GT::Node *) const noexcept { return false; }
68 };
69
93 template <AlephGraph GT,
94 template <class, class> class Itor = Node_Arc_Iterator,
97 {
98 SA & sa;
99 GT *g_ptr = nullptr;
100
101 template <class Op>
102 bool find_path(typename GT::Node *curr, typename GT::Arc *arc,
103 Path<GT> & path, Op & op)
104 {
105 if (op(curr)) // goal node reached?
106 {
107 path.append(arc);
108 return true;
109 }
110
111 if (IS_NODE_VISITED(curr, Find_Path)) // has it been visited?
112 return false; // yes ==> there is no path from it
113
114 path.append(arc); // add curr_arc to the path
115 NODE_BITS(curr).set_bit(Find_Path, true);
116
117 // recursively search through curr_node's arcs
118 for (Itor<GT, SA> i(curr, sa); i.has_curr(); i.next())
119 {
120 auto next_arc = i.get_curr();
122 continue;
123
124 ARC_BITS(next_arc).set_bit(Find_Path, true);
126 if (find_path(next_node, next_arc, path, op))
127 return true; // a path was found
128 }
129
130 path.remove_last_node();
131
132 return false;
133 }
134
135 template <class Op>
136 bool find(const GT & g, typename GT::Node *start, Path<GT> & path, Op & op)
137 {
138 g_ptr = const_cast<GT *>(&g);
139 path.set_graph(g, start);
140
141 if (op(start))
142 return true;
143
146
147 NODE_BITS(start).set_bit(Find_Path, true);
148
149 // recursively explore each of start's arcs
150 for (Itor<GT, SA> i(start, sa); i.has_curr(); i.next())
151 {
152 auto arc = i.get_curr();
153 ARC_BITS(arc).set_bit(Find_Path, true);
154
155 auto next_node = g.get_connected_node(arc, start);
157 continue;
158
159 if (find_path(next_node, arc, path, op))
160 return true;
161 }
162
163 path.remove_last_node();
164
165 return false;
166 }
167
168 template <class Op>
169 bool find(const GT & g, typename GT::Node *start, Path<GT> & path, Op && op)
170 {
171 return find(g, start, path, op);
172 }
173
174 public:
176 : sa(__sa)
177 { /* empty */
178 }
179
181 : sa(__sa)
182 { /* empty */
183 }
184
195 bool operator ()(const GT & g,
196 typename GT::Node *start, typename GT::Node *end,
197 Path<GT> & path)
198 {
199 return find(g, start, path, [end](auto p) { return p == end; });
200 }
201
212 typename GT::Node *start,
213 typename GT::Node *end)
214 {
215 Path<GT> ret(g);
216 find(g, start, ret, [end](auto p) { return p == end; });
217 return ret;
218 }
219
232 template <class Op>
233 Path<GT> operator ()(const GT & g, typename GT::Node *start, Op & op)
234 {
235 Path<GT> ret(g);
236 find<Op>(g, start, ret, op);
237 return ret;
238 }
239
240 template <class Op = Dft_Goal_Node<GT>>
241 Path<GT> operator ()(const GT & g, typename GT::Node *start, Op && op)
242 {
243 Path<GT> ret(g);
244 find<Op>(g, start, ret, op);
245 return ret;
246 }
247 };
248
249
272 template <AlephGraph GT,
273 template <typename, class> class Itor = Node_Arc_Iterator,
276 {
277 SA & sa;
278
279 template <class Op>
280 bool find_path(const GT & g, typename GT::Node *start,
281 Path<GT> & path, Op & op)
282 {
283 if (not path.inside_graph(g))
284 ah_invalid_argument_if(true) << "Path does not belong to graph";
285
286 path.empty(); // clear anything that may be in path
287 g.reset_nodes();
288 g.reset_arcs();
289
291
292 for (Itor<GT, SA> i(start, sa); i.has_curr(); i.next())
293 q.put(i.get_current_arc());
294
295 NODE_BITS(start).set_bit(Find_Path, true); // mark it visited
296
297 typename GT::Node *end = nullptr;
298
299 while (not q.is_empty()) // while arcs remain to be visited
300 {
301 auto arc = q.get();
302 auto src = g.get_src_node(arc);
303 auto tgt = g.get_tgt_node(arc);
304
306 continue;
307
308 if (IS_NODE_VISITED(tgt, Find_Path))
309 std::swap(src, tgt);
310
311 ARC_BITS(arc).set_bit(Find_Path, true);
312 NODE_BITS(tgt).set_bit(Find_Path, true);
313 NODE_COOKIE(tgt) = src;
314
315 if (op(tgt)) // was a path satisfying op found?
316 {
317 end = tgt;
318 break;
319 }
320
321 for (Itor<GT, SA> i(tgt); i.has_curr(); i.next())
322 {
323 auto a = i.get_current_arc();
324 if (IS_ARC_VISITED(a, Find_Path)) // arc visited?
325 continue; // yes ==> move on to the next one
326
327 // check the arc's nodes to see whether they were visited
330 continue; // nodes already visited ==> do not enqueue the arc
331
332 q.put(a);
333 }
334 }
335
336 if (not end)
337 return false;
338
339 q.empty();
340 path.insert(end);
341 auto p = end;
342 while (p != start)
343 {
344 p = (typename GT::Node *) NODE_COOKIE(p);
345 path.insert(p);
346 }
347
348 return true;
349 }
350
351 template <class Op>
352 bool find_path(const GT & g, typename GT::Node *start,
353 Path<GT> & path, Op && op)
354 {
355 return find_path(g, start, path, op);
356 }
357
358 public:
360 : sa(_sa)
361 { /* Empty */
362 }
363
365 : sa(_sa)
366 { /* Empty */
367 }
368
378 template <class Op>
379 Path<GT> operator ()(const GT & g, typename GT::Node *start, Op & op)
380 {
381 Path<GT> ret(g);
382 find_path(g, start, ret, op);
383 return ret;
384 }
385
386 template <class Op>
387 Path<GT> operator ()(const GT & g, typename GT::Node *start, Op && op)
388 {
389 Path<GT> ret(g);
390 find_path(g, start, ret, op);
391 return ret;
392 }
393
404 bool operator ()(const GT & g, typename GT::Node *start,
405 typename GT::Node *end, Path<GT> & path)
406 {
407 return find_path(g, start, path, [end](auto p) { return p == end; });
408 }
409
420 typename GT::Node *start, typename GT::Node *end)
421 {
422 Path<GT> ret(g);
423 find_path(g, start, ret, [end](auto p) { return p == end; });
424 return ret;
425 }
426 };
427
433 template <AlephGraph GT,
434 template <typename, class> class Itor = Out_Iterator,
437 {
438 const GT & g;
439 SA & sa;
440
441 template <template <typename T> class Q, class Op>
442 Path<GT> find(typename GT::Node *start, Op & op)
443 {
444 g.reset_nodes();
445 g.reset_arcs();
446
447 start->set_state(Processed);
448
450 for (Itor<GT, SA> it(start, sa); it.has_curr(); it.next())
451 {
452 auto a = it.get_curr();
453 g.get_tgt_node(a)->set_state(Processing);
454 a->set_state(Processing);
455 q.put(a);
456 }
457
458 typename GT::Node *end = nullptr, *curr = nullptr;
459 while (not q.is_empty())
460 {
461 auto arc = q.get();
462 assert(arc->state() == Processing);
463 arc->set_state(Processed);
464
465 curr = g.get_tgt_node(arc);
466 if (curr->state() == Processed)
467 continue;
468
469 curr->set_state(Processed);
470 NODE_COOKIE(curr) = g.get_src_node(arc);
471
472 if (op(curr))
473 {
474 end = curr;
475 break;
476 }
477
478 for (Itor<GT, SA> it(curr, sa); it.has_curr(); it.next())
479 {
480 auto a = it.get_curr();
482
483 auto tgt = g.get_tgt_node(a);
484 if (tgt->state() == Processed)
485 continue;
486
487 if (tgt->state() != Processed)
488 {
489 q.put(a);
490 tgt->set_state(Processing);
491 }
492 else
493 a->set_state(Processed);
494 }
495 } // end while
496
497 Path<GT> ret(g);
498 if (not end)
499 return ret;
500
501 assert(curr == end);
502
503 while (curr != start)
504 {
505 ret.insert(curr);
506 curr = (typename GT::Node *) NODE_COOKIE(curr);
507 }
508 ret.insert(start);
509
510 return ret;
511 }
512
513 public:
514 Directed_Find_Path(const GT & __g, SA & __sa) : g(__g), sa(__sa) {}
515
516 Directed_Find_Path(const GT & __g, SA && __sa = SA()) : g(__g), sa(__sa) {}
517
518 template <class Op>
519 Path<GT> dfs(typename GT::Node *start, Op & op)
520 {
521 return find<DynListStack, Op>(start, op);
522 }
523
524 template <class Op>
525 Path<GT> dfs(typename GT::Node *start, Op && op)
526 {
527 return find<DynListStack, Op>(start, op);
528 }
529
530 template <class Op>
531 Path<GT> bfs(typename GT::Node *start, Op & op)
532 {
533 return find<DynListQueue, Op>(start, op);
534 }
535
536 template <class Op>
537 Path<GT> bfs(typename GT::Node *start, Op && op)
538 {
539 return find<DynListQueue, Op>(start, op);
540 }
541
542 Path<GT> dfs(typename GT::Node *start, typename GT::Node *end)
543 {
544 return dfs(start, [end](auto p) { return p == end; });
545 }
546
547 Path<GT> bfs(typename GT::Node *start, typename GT::Node *end)
548 {
549 return bfs(start, [end](auto p) { return p == end; });
550 }
551 };
552} // namespace Aleph
553
554# endif // TPL_FIND_PATH_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.
List_Graph< Graph_Node< Node_Info >, Graph_Arc< Arc_Info > > GT
Path search on directed graphs defined through a graph class (not a digraph).
Directed_Find_Path(const GT &__g, SA &__sa)
Path< GT > dfs(typename GT::Node *start, Op &&op)
Path< GT > dfs(typename GT::Node *start, Op &op)
Path< GT > bfs(typename GT::Node *start, typename GT::Node *end)
Path< GT > dfs(typename GT::Node *start, typename GT::Node *end)
Directed_Find_Path(const GT &__g, SA &&__sa=SA())
Path< GT > find(typename GT::Node *start, Op &op)
Path< GT > bfs(typename GT::Node *start, Op &&op)
Path< GT > bfs(typename GT::Node *start, Op &op)
Dynamic queue of elements of generic type T based on single linked list.
T & put(const T &data)
The type of element.
T get()
Remove the oldest item of the queue.
void empty() noexcept
Empty the queue.
bool is_empty() const noexcept
Return true if this is empty.
Performs a breadth-first search for a path between a pair of nodes.
Path< GT > operator()(const GT &g, typename GT::Node *start, Op &op)
Invokes the breadth-first path search.
bool find_path(const GT &g, typename GT::Node *start, Path< GT > &path, Op &&op)
bool find_path(const GT &g, typename GT::Node *start, Path< GT > &path, Op &op)
Performs a depth-first search for a path between a pair of nodes.
Find_Path_Depth_First(SA &&__sa=SA())
bool operator()(const GT &g, typename GT::Node *start, typename GT::Node *end, Path< GT > &path)
Invokes the depth-first path search.
bool find(const GT &g, typename GT::Node *start, Path< GT > &path, Op &&op)
bool find_path(typename GT::Node *curr, typename GT::Arc *arc, Path< GT > &path, Op &op)
bool find(const GT &g, typename GT::Node *start, Path< GT > &path, Op &op)
Filtered iterator for outcoming arcs of a node.
Definition tpl_graph.H:1831
Path on a graph.
Definition tpl_graph.H:2772
void insert(Arc *arc)
Insert an arc as the first of a path.
Definition tpl_graph.H:3118
void empty()
Clean the path: all the nodes and arc are removed.
Definition tpl_graph.H:2922
bool inside_graph(const GT &gr) const noexcept
Return true if this is on graph gr
Definition tpl_graph.H:2850
void set_graph(const GT &__g, Node *start_node=nullptr)
Set the graph of the path.
Definition tpl_graph.H:2900
void append(Arc *arc)
Append an arc to the path.
Definition tpl_graph.H:2975
Node * remove_last_node()
Remove the last node of path.
Definition tpl_graph.H:3280
void set_state(unsigned int s) noexcept
Set the state to value s
Definition graph-dry.H:545
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_arcs() const
Reset all the arcs of graph (the control bits, the state, the counter and the cookie)
Definition graph-dry.H:975
Node * get_src_node(Arc *arc) const noexcept
Return the source node of arc (only for directed graphs)
Definition graph-dry.H:779
Node * get_connected_node(Arc *arc, Node *node) const noexcept
Return the adjacent node to node through arc.
Definition graph-dry.H:820
void reset_bit_arcs(int bit) const noexcept
Reset bit to zero for all the arcs of graph.
Definition graph-dry.H:1094
void reset_nodes() const
Reset all the nodes of graph (the control bits, the state, the counter and the cookie)
Definition graph-dry.H:968
Node * get_tgt_node(Arc *arc) const noexcept
Return the target node of arc (only for directed graphs)
Definition graph-dry.H:785
const unsigned char Processed
The node or arc has already been processed.
Definition aleph-graph.C:39
const unsigned char Processing
The node are being processed; probably it is inside a queue, stack or heap.
Definition aleph-graph.C:38
#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 NODE_COOKIE(p)
Return the node cookie
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
#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.
@ Find_Path
Definition aleph-graph.H:76
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
and
Check uniqueness with explicit hash + equality functors.
bool operator()(typename GT::Node *) const noexcept
Default filter for filtered iterators on arcs.
Definition tpl_graph.H:1001
Filtered iterator of adjacent arcs of a node.
Definition tpl_graph.H:1120
Dynamic queue implementation based on linked lists.
Dynamic stack implementation based on linked lists.
Utility algorithms and operations for graphs.