aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
defaultPartialOrderedEliminationSequenceStrategy.cpp
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 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  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
26  */
27 
28 #include <agrum/agrum.h>
29 #include <agrum/tools/core/math/math_utils.h>
30 
31 #include <agrum/tools/graphs/algorithms/triangulations/eliminationStrategies/defaultPartialOrderedEliminationSequenceStrategy.h>
32 #include <agrum/tools/graphs/undiGraph.h>
33 
34 namespace gum {
35 
36  /// default constructor (uses an empty graph)
39  double theThreshold) :
42  // for debugging purposes
44  }
45 
46  /// constructor for an a priori non empty graph
50  const NodeProperty< Size >* dom_sizes,
51  const List< NodeSet >* subsets,
52  double ratio,
53  double threshold) :
58 
59  // for debugging purposes
61  }
62 
63  /// copy constructor
68  // no need to set log_weights__ because the copy of the simplicial set
69  // will set it properly
71  graph_,
74  false)),
78  // for debugging purposes
80  }
81 
82  /// move constructor
93  from.simplicial_set__ = nullptr;
94 
95  // for debugging purposes
97  }
98 
99  /// destructor
102  // for debugging purposes
104 
106  }
107 
108  /// create a new simplicial set suited for the current graph
110  // remove the old simplicial set, if any
111  if (simplicial_set__ != nullptr) {
112  delete simplicial_set__;
113  simplicial_set__ = nullptr;
114  }
115 
116  if (graph_ != nullptr) {
117  // create a simplicial set suited for the graph
120  &log_weights__,
123 
125  }
126  }
127 
128  /// sets a new graph to be triangulated
130  UndiGraph* graph,
131  const NodeProperty< Size >* domain_sizes) {
134  return true;
135  }
136 
137  return false;
138  }
139 
140  /// clears the sequence (to prepare, for instance, a new elimination sequence)
144 
145  if (simplicial_set__ != nullptr) {
146  delete simplicial_set__;
147  simplicial_set__ = nullptr;
148  }
149  }
150 
151  /// returns the best possible node to be eliminated
153  const PriorityQueue< NodeId, double >& possibleNodes) {
154  bool found = false;
155  double min_score = 0;
156  NodeId best_node = 0;
157 
158  for (const auto node: nodeset_) {
159  try {
160  double score = possibleNodes.priority(node);
161 
162  if (!found || (score < min_score)) {
163  found = true;
164  min_score = score;
165  best_node = node;
166  }
167  } catch (NotFound&) {}
168  }
169 
170  if (!found) { GUM_ERROR(NotFound, "no possible node to eliminate"); }
171 
172  return best_node;
173  }
174 
175  /// returns the new node to be eliminated within the triangulation algorithm
177  // if there is no simplicial set, send an exception
178  if (graph_ == nullptr) GUM_ERROR(NotFound, "the graph is empty");
179 
182  "the partial order does not cover all the nodes "
183  "of the graph");
184 
185  if (nodeset_.empty()) { GUM_ERROR(NotFound, "no node is admissible"); }
186 
187  // select a node to be eliminated: try simplicial nodes, then almost
188  // simplicial nodes, then quasi-simplicial nodes
189  // note that if graph_ != nullptr, simplicial_set__ has been allocated
190  try {
192  } catch (NotFound&) {}
193 
194  try {
196  } catch (NotFound&) {}
197 
198  try {
200  } catch (NotFound&) {}
201 
202  // here: select the node through Kjaerulff's heuristic
203  auto iter = nodeset_.cbegin();
204  double min_score = log_weights__[*iter];
205  NodeId best_node = *iter;
206 
207  for (++iter; iter != nodeset_.cend(); ++iter) {
208  double score = log_weights__[*iter];
209 
210  if (score < min_score) {
211  min_score = score;
212  best_node = *iter;
213  }
214  }
215 
216  return best_node;
217  }
218 
219  /** @brief if the elimination sequence is able to compute fill-ins, we
220  * indicatewhether we want this feature to be activated */
223 
225  }
226 
227  /** @brief indicates whether the new fill-ins generated by a new eliminated
228  * node, if needed, will be computed by the elimination sequence, or need be
229  * computed by the triangulation itself. */
231  return provide_fill_ins__;
232  }
233 
234  /** @brief indicates whether the elimination sequence updates by itself the
235  * graph after a node has been eliminated */
237  const {
238  return true;
239  }
240 
241  /// performs all the graph/fill-ins updates provided
243  const NodeId id) {
244  // check whether we can do something
245  if (simplicial_set__ != nullptr) {
248 
249  if (!partial_order_needed_) {
250  // remove the node from nodeset_
251  nodeset_.erase(id);
252 
253  if (nodeset_.empty()) {
254  // go to the next non-empty subset
256  for (const auto node: *subset_iter_) {
258  }
259  if (!nodeset_.empty()) break;
260  }
261  }
262  }
263  }
264  }
265 
266  /** @brief in case fill-ins are provided, this function returns the fill-ins
267  * generated after the last node elimination */
269  if (!provide_fill_ins__ || (simplicial_set__ == nullptr))
271  else
272  return simplicial_set__->fillIns();
273  }
274 
275  /** @brief creates a new elimination sequence of the same type as the current
276  * object, but this sequence contains only an empty graph */
282  }
283 
284  /// virtual copy constructor
288  }
289 
290 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669