aGrUM  0.14.2
defaultPartialOrderedEliminationSequenceStrategy.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 #include <agrum/core/math/math.h>
28 
30 #include <agrum/graphs/undiGraph.h>
31 
32 namespace gum {
33 
37  double theThreshold) :
38  __simplicial_ratio(theRatio),
39  __simplicial_threshold(theThreshold) {
40  // for debugging purposes
42  }
43 
48  const NodeProperty< Size >* dom_sizes,
49  const List< NodeSet >* subsets,
50  double ratio,
51  double threshold) :
52  __simplicial_ratio(ratio),
53  __simplicial_threshold(threshold) {
54  setGraph(graph, dom_sizes);
55  setPartialOrder(subsets);
56 
57  // for debugging purposes
59  }
60 
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 
85  __log_weights(std::move(from.__log_weights)),
90  __simplicial_set->replaceLogWeights(&from.__log_weights, &__log_weights);
91  from.__simplicial_set = nullptr;
92 
93  // for debugging purposes
95  }
96 
100  // for debugging purposes
102 
104  }
105 
108  // remove the old simplicial set, if any
109  if (__simplicial_set != nullptr) {
110  delete __simplicial_set;
111  __simplicial_set = nullptr;
112  }
113 
114  if (_graph != nullptr) {
115  // create a simplicial set suited for the graph
118  &__log_weights,
121 
123  }
124  }
125 
128  UndiGraph* graph, const NodeProperty< Size >* domain_sizes) {
129  if (PartialOrderedEliminationSequenceStrategy::setGraph(graph, domain_sizes)) {
131  return true;
132  }
133 
134  return false;
135  }
136 
140  __log_weights.clear();
141 
142  if (__simplicial_set != nullptr) {
143  delete __simplicial_set;
144  __simplicial_set = nullptr;
145  }
146  }
147 
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 
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 
219  __provide_fill_ins = do_it;
220 
222  }
223 
228  return __provide_fill_ins;
229  }
230 
234  const {
235  return true;
236  }
237 
240  const NodeId id) {
241  // check whether we can do something
242  if (__simplicial_set != nullptr) {
245 
246  if (!_partial_order_needed) {
247  // remove the node from _nodeset
248  _nodeset.erase(id);
249 
250  if (_nodeset.empty()) {
251  // go to the next non-empty subset
252  for (++_subset_iter; _subset_iter != _subsets->cend(); ++_subset_iter) {
253  for (const auto node : *_subset_iter) {
254  if (_graph->existsNode(node)) { _nodeset.insert(node); }
255  }
256  if (!_nodeset.empty()) break;
257  }
258  }
259  }
260  }
261  }
262 
266  if (!__provide_fill_ins || (__simplicial_set == nullptr))
268  else
269  return __simplicial_set->fillIns();
270  }
271 
278  }
279 
284  }
285 
286 } /* namespace gum */
Useful macros for maths.
virtual void clear()
clears the sequence (to prepare, for instance, a new elimination sequence)
void makeClique(const NodeId id)
adds the necessary edges so that node &#39;id&#39; and its neighbors form a clique
virtual const EdgeSet & fillIns()
in case fill-ins are provided, this function returns the fill-ins due to all the nodes eliminated so ...
virtual void clear() final
clears the sequence (to prepare, for instance, a new elimination sequence)
void __createSimplicialSet()
create a new simplicial set suited for the current graph
bool empty() const noexcept
Indicates whether the set is the empty set.
Definition: set_tpl.h:704
UndiGraph * _graph
the graph to be triangulated
virtual void eliminationUpdate(const NodeId node) final
performs all the graph/fill-ins updates provided (if any)
virtual DefaultPartialOrderedEliminationSequenceStrategy * newFactory() const final
creates a new elimination sequence of the same type as the current object, but this sequence contains...
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 ...
void replaceLogWeights(NodeProperty< double > *old_weigths, NodeProperty< double > *new_weights)
reassigns a new set of cliques&#39; log weights (with the same content)
const Priority & priority(const Val &elt) const
Returns the priority of an instance of the value passed in argument.
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 ...
NodeProperty< double > _log_domain_sizes
the log of the domain sizes of the variables/nodes
void eraseClique(const NodeId id)
removes a node and its adjacent edges from the underlying graph
virtual bool setPartialOrder(const List< NodeSet > *subsets)
sets a new partial ordering constraint on the elimination sequence
STL namespace.
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
const_iterator cbegin() const
The usual unsafe begin iterator to parse the set.
Definition: set_tpl.h:521
void erase(const Key &k)
Erases an element from the set.
Definition: set_tpl.h:653
Base classes for undirected graphs.
virtual NodeId nextNodeToEliminate() final
returns the new node to be eliminated within the triangulation algorithm
Generic doubly linked lists.
Definition: list.h:369
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
double __simplicial_threshold
the threshold used by __simplicial_set to determine small cliques
An Elimination sequence algorithm that imposes a given partial ordering on the nodes elimination sequ...
NodeId __nodeToEliminate(const PriorityQueue< NodeId, double > &possibleNodes)
returns the best possible node to be eliminated
The class for generic Hash Tables.
Definition: hashTable.h:676
UndiGraph * graph() const noexcept
returns the current graph
SimplicialSet * __simplicial_set
the simplicial set used for determining the best nodes to eliminate
Base class for all elimination sequence algorithm that impose a given partial ordering on the nodes e...
const PriorityQueue< NodeId, double > & allSimplicialNodes()
returns all the simplicial nodes
virtual bool setGraph(UndiGraph *graph, const NodeProperty< Size > *dom_sizes)
sets a new graph to be triangulated
Class enabling fast retrieval of simplicial, quasi and almost simplicial nodes.
Definition: simplicialSet.h:57
const const_iterator & cend() const noexcept
The usual unsafe end iterator to parse the set.
Definition: set_tpl.h:536
virtual bool providesGraphUpdate() const final
indicates whether the elimination sequence updates by itself the graph after a node has been eliminat...
NodeSet _nodeset
the nodes which can be currently eliminated
const List< NodeSet > * _subsets
the subsets constituting the partial ordering
bool existsNode(const NodeId id) const
returns true iff the NodeGraphPart contains the given nodeId
virtual DefaultPartialOrderedEliminationSequenceStrategy * copyFactory() const final
virtual copy constructor
virtual bool setGraph(UndiGraph *graph, const NodeProperty< Size > *dom_sizes) final
sets a new graph to be triangulated
Base class for undirected graphs.
Definition: undiGraph.h:106
const PriorityQueue< NodeId, double > & allAlmostSimplicialNodes()
returns all the almost simplicial nodes
List< NodeSet >::const_iterator _subset_iter
the iterator indicating which is the current subset on which we work
bool _partial_order_needed
indicate whether a new partial ordering is necessary for the elimination
DefaultPartialOrderedEliminationSequenceStrategy(double theRatio=GUM_QUASI_RATIO, double theThreshold=GUM_WEIGHT_THRESHOLD)
default constructor (uses an empty graph)
const PriorityQueue< NodeId, double > & allQuasiSimplicialNodes()
returns all the quasi simplicial nodes
void setFillIns(bool on_off)
sets/unset the fill-ins storage in the standard triangulation procedure
An Elimination sequence algorithm that imposes a given partial ordering on the nodes elimination sequ...
Size NodeId
Type for node ids.
Definition: graphElements.h:97
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:610
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
const EdgeSet & fillIns() const
returns the set of all the fill-ins added to the graph so far