Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_components.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
51# ifndef TPL_COMPONENTS_H
52# define TPL_COMPONENTS_H
53
54# include <tpl_agraph.H>
55# include <ah-errors.H>
56
57namespace Aleph {
58
101template <class GT, class SA = Dft_Show_Arc<GT>>
103{
105 const GT * gptr = nullptr;
106 size_t count = 0;
107
108public:
109
115 Build_Subgraph(SA arc_filter = SA())
116 : sa(arc_filter) { /* empty */ }
117
118 private:
119
120 // Recursive DFS to build mapped subgraph
121 void build_subgraph(GT & sg, typename GT::Node * g_src)
122 {
124 return;
125
126 // Mark source node as visited
127 NODE_BITS(g_src).set_bit(Build_Subtree, true);
128 ++count;
129
130 // Get or create mapped node in subgraph
132 if (sg_src == nullptr)
133 {
134 sg_src = sg.insert_node(g_src->get_info());
136 }
137
138 // Explore adjacent arcs
139 for (Node_Arc_Iterator<GT, SA> i(g_src, sa); i.has_curr(); i.next_ne())
140 {
141 auto arc = i.get_current_arc_ne();
143 continue;
144
145 // Mark arc as visited
146 ARC_BITS(arc).set_bit(Build_Subtree, true);
147
148 // Get or create mapped target node
149 auto g_tgt = i.get_tgt_node();
151 if (sg_tgt == nullptr)
152 {
153 sg_tgt = sg.insert_node(g_tgt->get_info());
155 }
156
157 // Insert arc in subgraph and establish mapping
158 auto sg_arc = sg.insert_arc(sg_src, sg_tgt, arc->get_info());
159 GT::map_arcs(arc, sg_arc);
160
161 // Recurse on target node
163 }
164 }
165
166 // Recursive DFS to build list of reachable nodes
167 template <template <class> class List>
169 {
171 return;
172
173 // Mark node as visited and add to list
174 NODE_BITS(p).set_bit(Build_Subtree, true);
175 ++count;
176 l.append(p);
177
178 // Explore adjacent arcs
179 for (Node_Arc_Iterator<GT, SA> it(p, sa);
180 count < gptr->get_num_nodes() and it.has_curr(); it.next_ne())
181 {
182 auto arc = it.get_current_arc_ne();
184 continue;
185
186 // Mark arc as visited and recurse
187 ARC_BITS(arc).set_bit(Build_Subtree, true);
188 build_subgraph(l, it.get_tgt_node());
189 }
190 }
191
192public:
193
209 void operator () (const GT & g, GT & sg, typename GT::Node * g_src)
210 {
211 ah_invalid_argument_if(g_src == nullptr)
212 << "Build_Subgraph: source node cannot be null";
213
214 gptr = &g;
215 count = 0;
217 }
218
229 GT operator () (const GT & g, typename GT::Node * src)
230 {
231 ah_invalid_argument_if(src == nullptr)
232 << "Build_Subgraph: source node cannot be null";
233
234 GT sg;
235 gptr = &g;
236 count = 0;
237 build_subgraph(sg, src);
238 return sg;
239 }
240
255 typename GT::Node * src)
256 {
257 ah_invalid_argument_if(src == nullptr)
258 << "Build_Subgraph: source node cannot be null";
259
260 gptr = &g;
261 count = 0;
262 build_subgraph<DynList>(list, src);
263 }
264};
265
266
313template <class GT, class SA = Dft_Show_Arc<GT>>
315{
317
318public:
319
326 : sa(arc_filter) { /* empty */ }
327
336 template <template <class> class List>
337 void compute_blocks(const GT & g, List<GT> & list)
338 {
339 g.reset_nodes();
340 g.reset_arcs();
341 size_t count = 0; // Count of visited nodes
342
343 for (typename GT::Node_Iterator it(g);
344 count < g.get_num_nodes() and it.has_curr(); it.next_ne())
345 {
346 auto curr = it.get_current_node_ne();
348 continue;
349
350 // Create new subgraph for this component
351 GT & subgraph = list.append(GT());
352
354 build(g, subgraph, curr);
355
356 count += subgraph.get_num_nodes();
357 }
358 }
359
368 template <template <class> class List>
370 {
371 g.reset_nodes();
372 g.reset_arcs();
373 size_t count = 0; // Count of visited nodes
374
375 for (typename GT::Node_Iterator i(g);
376 count < g.get_num_nodes() and i.has_curr(); i.next_ne())
377 {
378 auto curr = i.get_current_node_ne();
380 continue;
381
382 // Create new node list for this component
383 auto & l = list.append(List<typename GT::Node*>());
384
386 build(g, l, curr);
387
388 count += l.size();
389 }
390 }
391
405 void operator () (const GT & g, DynList<GT> & list)
406 {
408 }
409
423 {
424 compute_lists<DynList>(g, list);
425 }
426
439
447 bool is_connected(const GT & g)
448 {
449 if (g.get_num_nodes() <= 1)
450 return true;
451 return count_components(g) == 1;
452 }
453};
454
455
456} // end namespace Aleph
457
458# endif // TPL_COMPONENTS_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
Build a mapped subgraph from a graph starting at a given node.
void operator()(const GT &g, GT &sg, typename GT::Node *g_src)
Build a mapped subgraph starting from a specific node.
void build_subgraph(List< typename GT::Node * > &l, typename GT::Node *p)
void build_subgraph(GT &sg, typename GT::Node *g_src)
Build_Subgraph(SA arc_filter=SA())
Construct a subgraph builder with optional arc filter.
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
T & append(const T &item)
Append a new item by copy.
Definition htlist.H:1562
void next_ne() noexcept
Advances the iterator to the next filtered element (noexcept version).
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
Definition tpl_graph.H:524
Arc * insert_arc(Node *src_node, Node *tgt_node, void *a)
Definition tpl_graph.H:604
Compute the connected components of a graph.
void compute_blocks(const GT &g, List< GT > &list)
Compute connected components as mapped subgraphs.
Unconnected_Components(SA arc_filter=SA())
Construct a component finder with optional arc filter.
void compute_lists(const GT &g, List< List< typename GT::Node * > > &list)
Compute connected components as lists of node pointers.
void operator()(const GT &g, DynList< GT > &list)
Compute connected components as mapped subgraphs.
size_t count_components(const GT &g)
Count the number of connected components in a graph.
bool is_connected(const GT &g)
Check if a graph is connected.
void reset_arcs() const
Reset all the arcs of graph (the control bits, the state, the counter and the cookie)
Definition graph-dry.H:927
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
Definition graph-dry.H:695
static void map_arcs(A1 *p, A2 *q) noexcept
Map the arcs through their cookies.
Definition graph-dry.H:1026
void reset_nodes() const
Reset all the nodes of graph (the control bits, the state, the counter and the cookie)
Definition graph-dry.H:920
static void map_nodes(N1 *p, N2 *q) noexcept
Map the nodes through their cookies.
Definition graph-dry.H:995
List_Graph< Graph_Node< int >, Graph_Arc< int > > GT
#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.
@ Build_Subtree
Definition aleph-graph.H:80
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
DynList< T > maps(const C &c, Op op)
Classic map operation.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
Filtered iterator of adjacent arcs of a node.
Definition tpl_graph.H:1119
Array-based graph implementation.
DynList< int > l