Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
Prim.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
90# ifndef PRIM_H
91# define PRIM_H
92
93# include <ah-graph-concepts.H>
94
95# include <tpl_agraph.H>
96# include <tpl_graph_utils.H>
97# include <archeap.H>
98# include <ah-errors.H>
99# include <cookie_guard.H>
100
101namespace Aleph
102{
103 using namespace Aleph;
104
105 template <AlephGraph GT>
107 {
108 typename GT::Node *tree_node = nullptr; // image in the spanning tree
109 void *heap_node = nullptr; // pointer into the dedicated heap
110
111 Prim_Info() : tree_node(nullptr), heap_node(nullptr)
112 { /* empty */
113 }
114 };
115
116# define PRIMINFO(p) static_cast<Prim_Info<GT>*>(NODE_COOKIE(p))
117# define TREENODE(p) (PRIMINFO(p)->tree_node)
118# define HEAPNODE(p) (PRIMINFO(p)->heap_node)
119
120 template <class GT, class Distance>
122 {
123 // Returns reference to the heap_node pointer stored in Prim_Info
124 // The actual type is determined by ArcHeap, but stored as void*
125 void *& operator ()(typename GT::Node *p)
126 {
127 return PRIMINFO(p)->heap_node;
128 }
129 };
130
131 template <class GT, class Distance>
133 {
134 // Returns reference to the cookie pointer used as heap node storage
135 void *& operator ()(typename GT::Node *p)
136 {
137 return p->cookie;
138 }
139 };
140
141 template <class GT>
143 {
145
147 { /* empty */
148 }
149
150 void operator ()(const GT & g, typename GT::Node *p)
151 {
153 NODE_COOKIE(p) = new Prim_Info<GT>;
155 }
156 };
157
158 template <AlephGraph GT>
160 {
161 void operator ()(const GT &, typename GT::Node *p)
162 {
163 const Prim_Info<GT> *aux = PRIMINFO(p);
164 GT::map_nodes(p, TREENODE(p));
165 delete aux;
166 }
167 };
168
169
211 template <AlephGraph GT,
212 class Distance = Dft_Dist<GT>,
215 {
217
219
221
223
225 SA sa;
226
227 public:
234 : dist(__dist), sa(__sa)
235 {
236 // empty
237 }
238
239 private:
240 void paint_min_spanning_tree(const GT & g, typename GT::Node *first)
241 {
242 ah_domain_error_if(g.is_digraph()) << "g is a digraph";
243
244 g.reset_nodes();
245 g.reset_arcs();
246
247 NODE_BITS(first).set_bit(Aleph::Spanning_Tree, true); // visited
248
250 for (Node_Arc_Iterator<GT, SA> it(first, sa); it.has_curr(); it.next_ne())
251 {
252 typename GT::Arc *arc = it.get_current_arc_ne();
253 heap.put_arc(arc, it.get_tgt_node_ne());
254 }
255
256 const size_t V1 = g.get_num_nodes() - 1;
257 size_t count = 0;
258
259 while (count < V1 and not heap.is_empty())
260 { // get the next smallest arc
261 typename GT::Arc *min_arc = heap.get_min_arc();
263 continue;
264
265 ARC_BITS(min_arc).set_bit(Aleph::Spanning_Tree, true);
266
267 typename GT::Node *src = g.get_src_node(min_arc);
268 typename GT::Node *tgt = g.get_tgt_node(min_arc);
271 continue; // this arc would close a cycle in the tree
272
273 typename GT::Node *tgt_node =
274 IS_NODE_VISITED(src, Aleph::Spanning_Tree) ? tgt : src;
275
276 NODE_BITS(tgt_node).set_bit(Aleph::Spanning_Tree, true);
277
278 // insert tgt_node's unvisited arcs into the heap
279 for (Node_Arc_Iterator<GT, SA> it(tgt_node, sa); it.has_curr();
280 it.next_ne())
281 {
282 typename GT::Arc *arc = it.get_current_arc_ne();
284 continue;
285
286 typename GT::Node *tgt = it.get_tgt_node_ne();
288 continue; // node visited ==> would cause a cycle
289
290 heap.put_arc(arc, tgt);
291 }
292
293 ++count;
294 ARC_BITS(min_arc).set_bit(Aleph::Spanning_Tree, true);
295 }
296 }
297
298 void min_spanning_tree(const GT & g, typename GT::Node *first, GT & tree)
299 {
300 ah_domain_error_if(g.is_digraph()) << "g is a digraph";
301
302 clear_graph(tree);
303
306 g.reset_arcs();
307
308 // Scope guard for exception safety - ensures Uninit is always called
309 Scope_Guard cleanup_guard(g, [](const GT & graph) {
311 });
312
313 NODE_BITS(first).set_bit(Aleph::Spanning_Tree, true); // visited
314
315 Heap heap(dist, Acc_Heap());
316 // insert the first node's initial arcs into the heap
317 for (Node_Arc_Iterator<GT, SA> it(first, sa); it.has_curr(); it.next_ne())
318 {
319 typename GT::Arc *arc = it.get_current_arc_ne();
320 heap.put_arc(arc, it.get_tgt_node_ne());
321 }
322
323 const size_t V1 = g.get_num_nodes() - 1;
324
325 while (tree.get_num_arcs() < V1 and not heap.is_empty())
326 { // get the next smallest arc
327 typename GT::Arc *min_arc = heap.get_min_arc();
329 continue;
330
331 ARC_BITS(min_arc).set_bit(Aleph::Spanning_Tree, true);
332
333 typename GT::Node *src = g.get_src_node(min_arc);
334 typename GT::Node *tgt = g.get_tgt_node(min_arc);
337 continue; // this arc would close a cycle in the tree
338
339 typename GT::Node *tgt_node =
340 IS_NODE_VISITED(src, Aleph::Spanning_Tree) ? tgt : src;
341
342 NODE_BITS(tgt_node).set_bit(Aleph::Spanning_Tree, true);
343
344 // insert tgt_node's unvisited arcs into the heap
345 for (Node_Arc_Iterator<GT, SA> it(tgt_node, sa); it.has_curr();
346 it.next_ne())
347 {
348 typename GT::Arc *arc = it.get_current_arc_ne();
350 continue;
351
352 typename GT::Node *tgt = it.get_tgt_node_ne();
354 continue; // node visited ==> would cause a cycle
355
356 heap.put_arc(arc, tgt);
357 }
358
359 // insert the new arc into tree and map it
360 typename GT::Arc *tree_arc =
361 tree.insert_arc(TREENODE(src), TREENODE(tgt), min_arc->get_info());
362 GT::map_arcs(min_arc, tree_arc);
363 }
364
365 // cleanup_guard destructor will call Uninit_Prim_Info for all nodes
366 }
367
368 public:
381 void operator ()(const GT & g, GT & tree)
382 {
383 min_spanning_tree(g, g.get_first_node(), tree);
384 }
385
399 void operator ()(const GT & g, typename GT::Node *start, GT & tree)
400 {
401 min_spanning_tree(g, start, tree);
402 }
403
405 void operator ()(const GT & g)
406 {
408 }
409
410 void operator ()(const GT & g, typename GT::Node *start)
411 {
412 paint_min_spanning_tree(g, start);
413 }
414 };
415
416
417# undef HEAPNODE
418# undef TREENODE
419# undef PRIMINFO
420} // end namespace Aleph
421
422# endif // PRIM_H
#define TREENODE(p)
Definition Dijkstra.H:122
#define PRIMINFO(p)
Definition Prim.H:116
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
Definition ah-errors.H:527
C++20 concepts for the protocol shared by graph algorithms.
Arc heap for graph algorithms.
List_Graph< Graph_Node< Node_Info >, Graph_Arc< Arc_Info > > GT
Default distance accessor for arc weights.
void next_ne() noexcept
Advances the iterator to the next filtered element (noexcept version).
bool is_empty() const noexcept
Node * get_first_node() const
Return any node in the graph.
Definition tpl_graph.H:577
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
Functor that traverses the nodes of a graph and performs an operation.
Definition tpl_graph.H:2638
Computes the minimum spanning tree of a graph using Prim's algorithm.
Definition Prim.H:215
void paint_min_spanning_tree(const GT &g, typename GT::Node *first)
Definition Prim.H:240
void min_spanning_tree(const GT &g, typename GT::Node *first, GT &tree)
Definition Prim.H:298
Prim_Min_Spanning_Tree(Distance __dist=Distance(), SA __sa=SA())
Constructor.
Definition Prim.H:233
ArcHeap< GT, Distance, Acc_Simple_Heap > Simple_Heap
Definition Prim.H:222
ArcHeap< GT, Distance, Acc_Heap > Heap
Definition Prim.H:220
void operator()(const GT &g, GT &tree)
Invokes the computation of the minimum spanning tree using Prim's algorithm.
Definition Prim.H:381
Prim_Heap_Info< GT, Distance > Acc_Heap
Definition Prim.H:216
Simple_Prim_Heap< GT, Distance > Acc_Simple_Heap
Definition Prim.H:218
Generic RAII scope guard for cleanup operations on graphs.
void put_arc(typename GT::Arc *arc, typename GT::Node *tgt)
Insert or update an arc associated with a target node, keeping the smallest-distance arc per node in ...
Definition archeap.H:107
GT::Arc * get_min_arc()
Extract the arc with minimum distance from the heap and clear its node-to-heap mapping.
Definition archeap.H:136
ArcInfo & get_info() noexcept
Return a modifiable reference to the arc data.
Definition graph-dry.H:637
NodeInfo & get_info() noexcept
Return a modifiable reference to the data contained in the node.
Definition graph-dry.H:536
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
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
Definition graph-dry.H:737
bool is_digraph() const noexcept
Return true if the graph this is directed.
Definition graph-dry.H:699
static void map_arcs(A1 *p, A2 *q) noexcept
Map the arcs through their cookies.
Definition graph-dry.H:1074
void reset_bit(Node *node, int bit) const noexcept
Reset the bit of node (to zero)
Definition graph-dry.H:849
constexpr size_t get_num_arcs() const noexcept
Definition graph-dry.H:826
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
static void map_nodes(N1 *p, N2 *q) noexcept
Map the nodes through their cookies.
Definition graph-dry.H:1043
RAII guards for graph node/arc cookies.
#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
void clear_graph(GT &g) noexcept
Clean a graph: all its nodes and arcs are removed and freed.
Definition tpl_graph.H:3659
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.
@ Spanning_Tree
Definition aleph-graph.H:79
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
and
Check uniqueness with explicit hash + equality functors.
static std::atomic< bool > init
Definition hash-fct.C:54
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
Default filter for filtered iterators on arcs.
Definition tpl_graph.H:1001
void operator()(const GT &g, typename GT::Node *p)
Definition Prim.H:150
Init_Prim_Info(GT &__tree)
Definition Prim.H:146
Filtered iterator of adjacent arcs of a node.
Definition tpl_graph.H:1120
void *& operator()(typename GT::Node *p)
Definition Prim.H:125
void * heap_node
Definition Prim.H:109
GT::Node * tree_node
Definition Prim.H:108
void *& operator()(typename GT::Node *p)
Definition Prim.H:135
void operator()(const GT &, typename GT::Node *p)
Definition Prim.H:161
Distance accessor.
Array-based graph implementation.
Utility algorithms and operations for graphs.