aGrUM  0.14.2
spanningForestPrim.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
26 #include <agrum/agrum.h>
27 
29 
30 namespace gum {
31 
34  const EdgeProperty< float >* cost) :
36  __graph(*graph), __costTable(*cost), __spanning_tree_cost(0),
37  __require_computation(true) {
38  if (!graph || !cost) {
39  GUM_ERROR(GraphError, "invalid null graph or edge cost pointer");
40  }
41 
42  // for debugging purposes
43  GUM_CONSTRUCTOR(SpanningForestPrim);
44  }
45 
46  // copy constructor
53  // for debugging purposes
54  GUM_CONS_CPY(SpanningForestPrim);
55  }
56 
57  // destructor
59  // for debugging purposes
60  GUM_DESTRUCTOR(SpanningForestPrim);
61  }
62 
66 
67  return __spanning_tree_cost;
68  }
69 
73 
74  return __spanning_tree.edges();
75  }
76 
80 
81  return __spanning_tree;
82  }
83 
86  // compute a spanning tree in every connected component
87  for (const auto node : __graph.nodes()) {
88  if (!__spanning_tree.existsNode(node)) { __computeInAComponent(node); }
89  }
90 
91  // indicate that everything was computed
92  __require_computation = false;
93  }
94 
97  // add the node to the spanning tree
99 
100  // explore its neighborhood
101  __exploreNode(id);
102 
103  // get the next nodes to link to the current spanning tree nodes
104 
105  while (!__edgesToExplore.empty()) {
106  const Edge edge = __edgesToExplore.pop();
107  const NodeId first = edge.first();
108  const NodeId second = edge.second();
109 
110  // consider only the edges that have one extremal node not in the spanning
111  // tree as those that can be added to the tree
112 
113  if (!__spanning_tree.existsNode(first)) {
114  // add the edge to the spanning tree
116  __spanning_tree.addEdge(first, second);
118 
119  // We must explore the first node's neighborhood
120  __exploreNode(first);
121  } else if (!__spanning_tree.existsNode(second)) {
122  // add the edge to the spanning tree
124  __spanning_tree.addEdge(first, second);
126 
127  // We must explore the second node
128  __exploreNode(second);
129  }
130  }
131  }
132 
135  // add its neighbors __edgesToExplore to indicate that they are
136  // potential next nodes to explore
137  for (const auto node : __graph.neighbours(id)) {
138  if (!__spanning_tree.existsNode(node)) {
139  Edge edge(node, id);
140  __edgesToExplore.insert(edge, __costTable[edge]);
141  }
142  }
143  }
144 
145 } /* namespace gum */
NodeId second() const
returns the node ID of the other extremal node ID
virtual void addNodeWithId(const NodeId id)
try to insert a node with the given id
const EdgeProperty< float > & __costTable
the costs of the edges
const UndiGraph & __graph
the graph the spanning tree of which we wish to compute
UndiGraph __spanning_tree
the computed spanning tree
SpanningForestPrim(const UndiGraph *graph, const EdgeProperty< float > *costTable)
Default constructor.
virtual void addEdge(const NodeId first, const NodeId second)
insert a new edge into the undirected graph
Definition: undiGraph_inl.h:32
const UndiGraph & spanningForest()
Construct the spanning forest.
The Prim algorithm for computing min cost spanning trees or forests.
void __computeInAComponent(const NodeId id)
compute a spanning tree in a given connected component of __graph
The Prim algorithm for computing min cost spanning trees or forests.
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
const EdgeSet & edgesInSpanningForest()
Returns the edges in a min cost spanning forest.
The class for generic Hash Tables.
Definition: hashTable.h:676
const NodeSet & neighbours(const NodeId id) const
returns the set of edges adjacent to a given node
float costOfSpanningForest()
Returns the cost of the spanning forest.
const EdgeSet & edges() const
returns the set of edges stored within the EdgeGraphPart
NodeId first() const
returns one extremal node ID (whichever one it is is unspecified)
const NodeGraphPart & nodes() const
return *this as a NodeGraphPart
virtual ~SpanningForestPrim()
Destructor.
bool existsNode(const NodeId id) const
returns true iff the NodeGraphPart contains the given nodeId
The base class for all undirected edges.
void __exploreNode(const NodeId id)
explore the neighborhood of a node belonging to the spanning tree
Base class for undirected graphs.
Definition: undiGraph.h:106
float __spanning_tree_cost
the cost of the spanning tree
void __compute()
Computes the spanning forest.
PriorityQueue< Edge, float > __edgesToExplore
the next edges that may be added to the spanning tree
Base class for computing min cost spanning trees or forests.
Size NodeId
Type for node ids.
Definition: graphElements.h:97
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
bool __require_computation
a Boolean indicating whether we need recompute the spanning tree