aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
defaultEliminationSequenceStrategy.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /** @file
23  * @brief An efficient unconstrained elimination sequence algorithm
24  *
25  * Class DefaultEliminationSequenceStrategy implements an unconstrained
26  * elimination sequence algorithm (that is, there is no external constraint on
27  * the possible elimination ordering). The ordering is determined as follows:
28  * # the nodes that are simplicial (i.e., those that already form a clique with
29  * their neighbors) are eliminated first
30  * # then the nodes that are almost simplicial (i.e. if we remove one of their
31  * neighbors, they become simplicial) and that create small cliques, are
32  * eliminated (see Bodlaender's safe reductions)
33  * # the quasi simplicial nodes (i.e., the nodes that do not require many
34  * fill-ins
35  * to create cliques) that would create small cliques, are eliminated
36  * # finally, the heuristic proposed by Kjaerulff(90) is used to compute the
37  * last nodes to be eliminated.
38  *
39  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
40  */
41 
42 #ifndef GUM_DEFAULT_ELIMINATION_SEQUENCE_STRATEGY_H
43 #define GUM_DEFAULT_ELIMINATION_SEQUENCE_STRATEGY_H
44 
45 
46 #include <agrum/agrum.h>
47 #include <agrum/tools/graphs/algorithms/simplicialSet.h>
48 #include <agrum/tools/graphs/algorithms/triangulations/eliminationStrategies/unconstrainedEliminationSequenceStrategy.h>
49 #include <agrum/tools/graphs/graphElements.h>
50 
51 
52 namespace gum {
53 
54 
55  /** @class DefaultEliminationSequenceStrategy
56  * @brief An efficient unconstrained elimination sequence algorithm
57  *
58  * Class DefaultEliminationSequenceStrategy implements an unconstrained
59  * elimination sequence algorithm (that is, there is no external constraint on
60  * the possible elimination ordering). The ordering is determined as follows:
61  * # the nodes that are simplicial (i.e., those that already form a clique
62  * with their neighbors) are eliminated first
63  * # then the nodes that are almost simplicial (i.e., if we remove one of
64  * their neighbors, they become simplicial) and that create small cliques,
65  * # are eliminated
66  * # the quasi simplicial nodes (i.e., the nodes that do not require many
67  * fill-ins to create cliques) that would create small cliques, are
68  * eliminated
69  * # finally, the heuristic proposed by Kjaerulff(90) is used to compute the
70  * last nodes to be eliminated.
71  *
72  * \ingroup graph_group
73  *
74  */
76  public:
77  // ############################################################################
78  /// @name Constructors / Destructors
79  // ############################################################################
80  /// @{
81 
82  /// default constructor (uses an empty graph)
83  /** @param theRatio the ratio used by the SimplicialSet included in the
84  * DefaultEliminationSequenceStrategy
85  * @param theThreshold the weight threshhold of the SimplicialSet included
86  * in the DefaultEliminationSequenceStrategy */
88  double theThreshold = GUM_WEIGHT_THRESHOLD);
89 
90  /// constructor for an a priori non empty graph
91  /** @param graph the graph to be triangulated, i.e., the nodes of which will
92  * be eliminated
93  * @param dom_sizes the domain sizes of the nodes to be eliminated
94  * @param ratio the ratio used by the SimplicialSet included in the
95  * DefaultEliminationSequenceStrategy
96  * @param threshold the weight threshhold of the SimplicialSet included in
97  * the DefaultEliminationSequenceStrategy
98  * @warning Note that we allow dom_sizes to be defined over nodes/variables
99  * that do not belong to graph. These sizes will simply be ignored. However,
100  * it is compulsory that all the nodes of graph belong to dom_sizes
101  * @warning the graph is altered during the triangulation.
102  * @warning note that, by aGrUM's rule, the graph and the domain sizes are
103  * not copied but only referenced by the elimination sequence algorithm. */
104  DefaultEliminationSequenceStrategy(UndiGraph* graph,
105  const NodeProperty< Size >* dom_sizes,
106  double ratio = GUM_QUASI_RATIO,
107  double threshold = GUM_WEIGHT_THRESHOLD);
108 
109  /// copy constructor
110  /** @warning The newly created elimination sequence strategy points toward
111  * the same undirected graph as the one contained in from but each strategy
112  * possesses its own simplicial set. As a result, if both elimination
113  * strategies are used at the same time, they will probably result in a mess
114  * because their simplicial sets won't be synchronized correctly with the
115  * changing undirected graph. So, whenever using this copy constructor, be
116  * sure that either from or the newly created strategy is used for a
117  * triangulation but not both. This will necessarily be OK in
118  * DefaultTriangulations. */
120 
121  /// move constructor
123 
124  /// destructor
126 
127  /** @brief creates a new elimination sequence of the same type as the
128  * current object, but this sequence contains only an empty graph
129  * @warning you must deallocate by yourself the object returned
130  * @return an empty clone of the current object with the same type */
131  virtual DefaultEliminationSequenceStrategy* newFactory() const final;
132 
133  /// virtual copy constructor
134  /** @warning The newly created elimination sequence strategy points toward
135  * the same undirected graph as the one contained in the current strategy
136  * but each strategy possesses its own simplicial set. As a result, if both
137  * elimination strategies are used at the same time, they will probably
138  * result in a mess because their simplicial sets won't be synchronized
139  * correctly with the changing undirected graph. So, whenever using this
140  * virtual copy constructor, be sure that either the current or the newly
141  * created strategy is used for a triangulation but not both. This will
142  * necessarily be OK in DefaultTriangulations. */
143  virtual DefaultEliminationSequenceStrategy* copyFactory() const final;
144 
145  /// @}
146 
147 
148  // ############################################################################
149  /// @name Accessors / Modifiers
150  // ############################################################################
151  /// @{
152 
153  /// sets a new graph to be triangulated
154  /** The elimination sequence algorithm reinitializes its data to start a new
155  * triangulation with Graph "graph"
156  * @param graph the new graph to be triangulated
157  * @param dom_sizes the domain sizes of the variables/nodes
158  * @return true if the data structures were modified (if the graph or the
159  * @warning Note that we allow dom_sizes to be defined over nodes/variables
160  * that do not belong to graph. These sizes will simply be ignored. However,
161  * it is compulsory that all the nodes of graph belong to dom_sizes
162  * @warning the graph is altered during the triangulation.
163  * @warning note that, by aGrUM's rule, the graph and the domain sizes are
164  * not copied but only referenced by the elimination sequence algorithm. */
165  virtual bool setGraph(UndiGraph* graph, const NodeProperty< Size >* dom_sizes) final;
166 
167  /** @brief clears the sequence (to prepare, for instance, a new elimination
168  * sequence) */
169  virtual void clear() final;
170 
171  /// returns the new node to be eliminated within the triangulation algorithm
172  /** @throws NotFound exception is thrown if there is no more node to
173  * eliminate in the graph */
174  virtual NodeId nextNodeToEliminate() final;
175 
176  /** @brief if the elimination sequence is able to compute fill-ins, we
177  * indicate whether we want this feature to be activated
178  *
179  * @param do_it when true and the elimination sequence has the ability to
180  * compute fill-ins, the elimination sequence will actually compute them
181  * (for the triangulation to use them), else they will not be available. */
182  virtual void askFillIns(bool do_it) final;
183 
184  /** @brief indicates whether the fill-ins generated by the eliminated
185  * nodes, if needed, will be computed by the elimination sequence, or need
186  * be computed by the triangulation itself.
187  *
188  * An elimination sequence provides fill-ins to its triangulation if and
189  * only if it has the ability to compute them and it has been asked to do so
190  * (by method askFillIns) */
191  virtual bool providesFillIns() const final;
192 
193  /** @brief indicates whether the elimination sequence updates by itself the
194  * graph after a node has been eliminated
195  *
196  * Some algorithms have more informations than the triangulation algorithm
197  * to update the graph after a node has been eliminated. They can thus
198  * exploit these informations to update the graph faster than the
199  * triangulation. Hence the latter should delegate this operation to the
200  * elimination sequence. This is the case, for instance, for the
201  * defaultEliminationSequence, which uses a SimplicialSet that knows that
202  * some eliminated nodes do not require any fill-in. */
203  virtual bool providesGraphUpdate() const final;
204 
205  /// performs all the graph/fill-ins updates provided (if any)
206  /** @param node the node the elimination of which requires the graph update
207  */
208  virtual void eliminationUpdate(const NodeId node) final;
209 
210  /** @brief in case fill-ins are provided, this function returns the fill-ins
211  * due to all the nodes eliminated so far */
212  virtual const EdgeSet& fillIns() final;
213 
214  /// @}
215 
216  private:
217  /// for each node, the weight of the clique created by the node's
218  /// elimination
220 
221  /// the simplicial set used for determining the best nodes to eliminate
223 
224  /// the ratio used by _simplicial_set_ for its quasi-simplicial nodes
226 
227  /// the threshold used by _simplicial_set_ to determine small cliques
229 
230  /// indicates whether we compute new fill-ins
231  bool _provide_fill_ins_{false};
232 
233 
234  /// create a new simplicial set suited for the current graph
235  void _createSimplicialSet_();
236  };
237 
238 
239 } /* namespace gum */
240 
241 
242 #endif /* GUM_DEFAULT_ELIMINATION_SEQUENCE_STRATEGY_H */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
virtual void eliminationUpdate(const NodeId node) final
performs all the graph/fill-ins updates provided (if any)
SimplicialSet * _simplicial_set_
the simplicial set used for determining the best nodes to eliminate
DefaultEliminationSequenceStrategy(UndiGraph *graph, const NodeProperty< Size > *dom_sizes, double ratio=GUM_QUASI_RATIO, double threshold=GUM_WEIGHT_THRESHOLD)
constructor for an a priori non empty graph
DefaultEliminationSequenceStrategy(double theRatio=GUM_QUASI_RATIO, double theThreshold=GUM_WEIGHT_THRESHOLD)
default constructor (uses an empty graph)
virtual bool providesFillIns() const final
indicates whether the fill-ins generated by the eliminated nodes, if needed, will be computed by the ...
virtual const EdgeSet & fillIns() final
in case fill-ins are provided, this function returns the fill-ins due to all the nodes eliminated so ...
An efficient unconstrained elimination sequence algorithm.
DefaultEliminationSequenceStrategy(DefaultEliminationSequenceStrategy &&)
move constructor
virtual void askFillIns(bool do_it) final
if the elimination sequence is able to compute fill-ins, we indicate whether we want this feature to ...
virtual bool providesGraphUpdate() const final
indicates whether the elimination sequence updates by itself the graph after a node has been eliminat...
NodeProperty< double > _log_weights_
for each node, the weight of the clique created by the node&#39;s elimination
double _simplicial_ratio_
the ratio used by simplicial_set for its quasi-simplicial nodes
DefaultEliminationSequenceStrategy(const DefaultEliminationSequenceStrategy &from)
copy constructor
virtual bool setGraph(UndiGraph *graph, const NodeProperty< Size > *dom_sizes) final
sets a new graph to be triangulated
void _createSimplicialSet_()
create a new simplicial set suited for the current graph
bool _provide_fill_ins_
indicates whether we compute new fill-ins
virtual void clear() final
clears the sequence (to prepare, for instance, a new elimination sequence)
virtual NodeId nextNodeToEliminate() final
returns the new node to be eliminated within the triangulation algorithm
double _simplicial_threshold_
the threshold used by simplicial_set to determine small cliques
virtual DefaultEliminationSequenceStrategy * copyFactory() const final
virtual copy constructor
virtual DefaultEliminationSequenceStrategy * newFactory() const final
creates a new elimination sequence of the same type as the current object, but this sequence contains...