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 <ah-graph-concepts.H>
55
56# include <tpl_agraph.H>
57# include <ah-errors.H>
58
59namespace Aleph {
60
103template <AlephGraph GT, ArcFilter<GT> SA = Dft_Show_Arc<GT>>
105{
106 SA sa;
107 const GT * gptr = nullptr;
108 size_t count = 0;
109
110public:
111
117 Build_Subgraph(SA arc_filter = SA())
118 : sa(arc_filter) { /* empty */ }
119
120 private:
121
122 // Recursive DFS to build mapped subgraph
123 void build_subgraph(GT & sg, typename GT::Node * g_src)
124 {
126 return;
127
128 // Mark source node as visited
129 NODE_BITS(g_src).set_bit(Build_Subtree, true);
130 ++count;
131
132 // Get or create mapped node in subgraph
134 if (sg_src == nullptr)
135 {
136 sg_src = sg.insert_node(g_src->get_info());
138 }
139
140 // Explore adjacent arcs
141 for (Node_Arc_Iterator<GT, SA> i(g_src, sa); i.has_curr(); i.next_ne())
142 {
143 auto arc = i.get_current_arc_ne();
145 continue;
146
147 // Mark arc as visited
148 ARC_BITS(arc).set_bit(Build_Subtree, true);
149
150 // Get or create mapped target node
151 auto g_tgt = i.get_tgt_node();
153 if (sg_tgt == nullptr)
154 {
155 sg_tgt = sg.insert_node(g_tgt->get_info());
157 }
158
159 // Insert arc in subgraph and establish mapping
160 auto sg_arc = sg.insert_arc(sg_src, sg_tgt, arc->get_info());
161 GT::map_arcs(arc, sg_arc);
162
163 // Recurse on target node
165 }
166 }
167
168 // Recursive DFS to build list of reachable nodes
169 template <template <class> class List>
171 {
173 return;
174
175 // Mark node as visited and add to list
176 NODE_BITS(p).set_bit(Build_Subtree, true);
177 ++count;
178 l.append(p);
179
180 // Explore adjacent arcs
181 for (Node_Arc_Iterator<GT, SA> it(p, sa);
182 count < gptr->get_num_nodes() and it.has_curr(); it.next_ne())
183 {
184 auto arc = it.get_current_arc_ne();
186 continue;
187
188 // Mark arc as visited and recurse
189 ARC_BITS(arc).set_bit(Build_Subtree, true);
190 build_subgraph(l, it.get_tgt_node());
191 }
192 }
193
194public:
195
211 void operator () (const GT & g, GT & sg, typename GT::Node * g_src)
212 {
213 ah_invalid_argument_if(g_src == nullptr)
214 << "Build_Subgraph: source node cannot be null";
215
216 gptr = &g;
217 count = 0;
219 }
220
231 GT operator () (const GT & g, typename GT::Node * src)
232 {
233 ah_invalid_argument_if(src == nullptr)
234 << "Build_Subgraph: source node cannot be null";
235
236 GT sg;
237 gptr = &g;
238 count = 0;
239 build_subgraph(sg, src);
240 return sg;
241 }
242
257 typename GT::Node * src)
258 {
259 ah_invalid_argument_if(src == nullptr)
260 << "Build_Subgraph: source node cannot be null";
261
262 gptr = &g;
263 count = 0;
264 build_subgraph<DynList>(list, src);
265 }
266};
267
268
315template <AlephGraph GT, ArcFilter<GT> SA = Dft_Show_Arc<GT>>
317{
318 SA sa;
319
320public:
321
327 Unconnected_Components(SA arc_filter = SA())
328 : sa(arc_filter) { /* empty */ }
329
338 template <template <class> class List>
339 void compute_blocks(const GT & g, List<GT> & list)
340 {
341 g.reset_nodes();
342 g.reset_arcs();
343 size_t count = 0; // Count of visited nodes
344
345 for (typename GT::Node_Iterator it(g);
346 count < g.get_num_nodes() and it.has_curr(); it.next_ne())
347 {
348 auto curr = it.get_current_node_ne();
350 continue;
351
352 // Create new subgraph for this component
353 GT & subgraph = list.append(GT());
354
356 build(g, subgraph, curr);
357
358 count += subgraph.get_num_nodes();
359 }
360 }
361
370 template <template <class> class List>
372 {
373 g.reset_nodes();
374 g.reset_arcs();
375 size_t count = 0; // Count of visited nodes
376
377 for (typename GT::Node_Iterator i(g);
378 count < g.get_num_nodes() and i.has_curr(); i.next_ne())
379 {
380 auto curr = i.get_current_node_ne();
382 continue;
383
384 // Create new node list for this component
385 auto & l = list.append(List<typename GT::Node*>());
386
388 build(g, l, curr);
389
390 count += l.size();
391 }
392 }
393
407 void operator () (const GT & g, DynList<GT> & list)
408 {
410 }
411
425 {
426 compute_lists<DynList>(g, list);
427 }
428
435 size_t count_components(const GT & g)
436 {
438 compute_lists<DynList>(g, components);
439 return components.size();
440 }
441
449 bool is_connected(const GT & g)
450 {
451 if (g.get_num_nodes() <= 1)
452 return true;
453 return count_components(g) == 1;
454 }
455};
456
457
458} // end namespace Aleph
459
460# 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:644
C++20 concepts for the protocol shared by graph algorithms.
List_Graph< Graph_Node< Node_Info >, Graph_Arc< Arc_Info > > GT
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.
Node belonging to a double circular linked list with header node.
Definition tpl_dnode.H:106
Doubly-linked list (defined in tpl_dynList.H).
Definition htlist.H:1155
T & append(const T &item)
Definition htlist.H:1271
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:1065
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
Definition tpl_graph.H:525
Arc * insert_arc(Node *src_node, Node *tgt_node, void *a)
Definition tpl_graph.H:605
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:975
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
Definition graph-dry.H:737
static void map_arcs(A1 *p, A2 *q) noexcept
Map the arcs through their cookies.
Definition graph-dry.H:1074
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
static void map_nodes(N1 *p, N2 *q) noexcept
Map the nodes through their cookies.
Definition graph-dry.H:1043
#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.
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.
@ Build_Subtree
Definition aleph-graph.H:80
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
and
Check uniqueness with explicit hash + equality functors.
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:1120
Array-based graph implementation.
DynList< int > l