aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
defaultPartialOrderedEliminationSequenceStrategy.cpp
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  * @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)
41  // for debugging purposes
43  }
44 
45  /// constructor for an a priori non empty graph
48  const NodeProperty< Size >* dom_sizes,
49  const List< NodeSet >* subsets,
50  double ratio,
51  double threshold) :
56 
57  // for debugging purposes
59  }
60 
61  /// copy constructor
66  // no need to set _log_weights_ because the copy of the simplicial set
67  // will set it properly
69  graph_,
72  false)),
76  // for debugging purposes
78  }
79 
80  /// move constructor
90  from._simplicial_set_ = nullptr;
91 
92  // for debugging purposes
94  }
95 
96  /// destructor
99  // for debugging purposes
101 
103  }
104 
105  /// create a new simplicial set suited for the current graph
107  // remove the old simplicial set, if any
108  if (_simplicial_set_ != nullptr) {
109  delete _simplicial_set_;
110  _simplicial_set_ = nullptr;
111  }
112 
113  if (graph_ != nullptr) {
114  // create a simplicial set suited for the graph
117  &_log_weights_,
120 
122  }
123  }
124 
125  /// sets a new graph to be triangulated
127  UndiGraph* graph,
128  const NodeProperty< Size >* domain_sizes) {
131  return true;
132  }
133 
134  return false;
135  }
136 
137  /// clears the sequence (to prepare, for instance, a new elimination sequence)
141 
142  if (_simplicial_set_ != nullptr) {
143  delete _simplicial_set_;
144  _simplicial_set_ = nullptr;
145  }
146  }
147 
148  /// returns the best possible node to be eliminated
150  const PriorityQueue< NodeId, double >& possibleNodes) {
151  bool found = false;
152  double min_score = 0;
153  NodeId best_node = 0;
154 
155  for (const auto node: nodeset_) {
156  try {
157  double score = possibleNodes.priority(node);
158 
159  if (!found || (score < min_score)) {
160  found = true;
161  min_score = score;
162  best_node = node;
163  }
164  } catch (NotFound&) {}
165  }
166 
167  if (!found) { GUM_ERROR(NotFound, "no possible node to eliminate") }
168 
169  return best_node;
170  }
171 
172  /// returns the new node to be eliminated within the triangulation algorithm
174  // if there is no simplicial set, send an exception
175  if (graph_ == nullptr) GUM_ERROR(NotFound, "the graph is empty")
176 
179  "the partial order does not cover all the nodes "
180  "of the graph");
181 
182  if (nodeset_.empty()) { GUM_ERROR(NotFound, "no node is admissible") }
183 
184  // select a node to be eliminated: try simplicial nodes, then almost
185  // simplicial nodes, then quasi-simplicial nodes
186  // note that if graph_ != nullptr, _simplicial_set_ has been allocated
187  try {
189  } catch (NotFound&) {}
190 
191  try {
193  } catch (NotFound&) {}
194 
195  try {
197  } catch (NotFound&) {}
198 
199  // here: select the node through Kjaerulff's heuristic
200  auto iter = nodeset_.cbegin();
201  double min_score = _log_weights_[*iter];
202  NodeId best_node = *iter;
203 
204  for (++iter; iter != nodeset_.cend(); ++iter) {
205  double score = _log_weights_[*iter];
206 
207  if (score < min_score) {
208  min_score = score;
209  best_node = *iter;
210  }
211  }
212 
213  return best_node;
214  }
215 
216  /** @brief if the elimination sequence is able to compute fill-ins, we
217  * indicatewhether we want this feature to be activated */
220 
222  }
223 
224  /** @brief indicates whether the new fill-ins generated by a new eliminated
225  * node, if needed, will be computed by the elimination sequence, or need be
226  * computed by the triangulation itself. */
228  return _provide_fill_ins_;
229  }
230 
231  /** @brief indicates whether the elimination sequence updates by itself the
232  * graph after a node has been eliminated */
234  return true;
235  }
236 
237  /// performs all the graph/fill-ins updates provided
239  // check whether we can do something
240  if (_simplicial_set_ != nullptr) {
243 
244  if (!partial_order_needed_) {
245  // remove the node from nodeset_
246  nodeset_.erase(id);
247 
248  if (nodeset_.empty()) {
249  // go to the next non-empty subset
251  for (const auto node: *subset_iter_) {
253  }
254  if (!nodeset_.empty()) break;
255  }
256  }
257  }
258  }
259  }
260 
261  /** @brief in case fill-ins are provided, this function returns the fill-ins
262  * generated after the last node elimination */
264  if (!_provide_fill_ins_ || (_simplicial_set_ == nullptr))
266  else
267  return _simplicial_set_->fillIns();
268  }
269 
270  /** @brief creates a new elimination sequence of the same type as the current
271  * object, but this sequence contains only an empty graph */
276  }
277 
278  /// virtual copy constructor
282  }
283 
284 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643