aGrUM 3.2.0
a C++ library for (probabilistic) graphical models
defaultPartialOrderedEliminationSequenceStrategy.cpp
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2026 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2026 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40
41
47
48#include <agrum/agrum.h>
49
52
54
55namespace gum {
56
59 DefaultPartialOrderedEliminationSequenceStrategy(double theRatio, double theThreshold) :
60 _simplicial_ratio_(theRatio), _simplicial_threshold_(theThreshold) {
61 // for debugging purposes
63 }
64
68 const NodeProperty< Size >* dom_sizes,
69 const List< NodeSet >* subsets,
70 double ratio,
71 double threshold) :
73 setGraph(graph, dom_sizes);
74 setPartialOrder(subsets);
75
76 // for debugging purposes
78 }
79
98
114
123
126 // remove the old simplicial set, if any
127 if (_simplicial_set_ != nullptr) {
128 delete _simplicial_set_;
129 _simplicial_set_ = nullptr;
130 }
131
132 if (graph_ != nullptr) {
133 // create a simplicial set suited for the graph
139
141 }
142 }
143
147 const NodeProperty< Size >* domain_sizes) {
150 return true;
151 }
152
153 return false;
154 }
155
166
169 const PriorityQueue< NodeId, double >& possibleNodes) {
170 bool found = false;
171 double min_score = 0;
172 NodeId best_node = 0;
173
174 for (const auto node: nodeset_) {
175 if (possibleNodes.contains(node)) {
176 double score = possibleNodes.priority(node);
177
178 if (!found || (score < min_score)) {
179 found = true;
180 min_score = score;
181 best_node = node;
182 }
183 }
184 }
185
186 if (!found) { GUM_ERROR(NotFound, "no possible node to eliminate") }
187
188 return best_node;
189 }
190
193 // if there is no simplicial set, send an exception
194 if (graph_ == nullptr) GUM_ERROR(NotFound, "the graph is empty")
195
198 "the partial order does not cover all the nodes "
199 "of the graph");
200
201 if (nodeset_.empty()) { GUM_ERROR(NotFound, "no node is admissible") }
202
203 // select a node to be eliminated: try simplicial nodes, then almost
204 // simplicial nodes, then quasi-simplicial nodes
205 // note that if graph_ != nullptr, _simplicial_set_ has been allocated
207 try {
209 } catch (NotFound const&) {}
210 }
211
213 try {
215 } catch (NotFound const&) {}
216 }
217
219 try {
221 } catch (NotFound const&) {}
222 }
223
224 // here: select the node through Kjaerulff's heuristic
225 auto iter = nodeset_.cbegin();
226 double min_score = _log_weights_[*iter];
227 NodeId best_node = *iter;
228
229 for (++iter; iter != nodeset_.cend(); ++iter) {
230 double score = _log_weights_[*iter];
231
232 if (score < min_score) {
233 min_score = score;
234 best_node = *iter;
235 }
236 }
237
238 return best_node;
239 }
240
248
255
261
264 // check whether we can do something
265 if (_simplicial_set_ != nullptr) {
268
270 // remove the node from nodeset_
271 nodeset_.erase(id);
272
273 if (nodeset_.empty()) {
274 // go to the next non-empty subset
275 for (++subset_iter_; subset_iter_ != subsets_->cend(); ++subset_iter_) {
276 for (const auto node: *subset_iter_) {
277 if (graph_->existsNode(node)) { nodeset_.insert(node); }
278 }
279 if (!nodeset_.empty()) break;
280 }
281 }
282 }
283 }
284 }
285
293
301
307
308} /* namespace gum */
An Elimination sequence algorithm that imposes a given partial ordering on the nodes elimination sequ...
NodeId nextNodeToEliminate() final
returns the new node to be eliminated within the triangulation algorithm
void eliminationUpdate(const NodeId node) final
performs all the graph/fill-ins updates provided (if any)
DefaultPartialOrderedEliminationSequenceStrategy * newFactory() const final
creates a new elimination sequence of the same type as the current object, but this sequence contains...
double _simplicial_threshold_
the threshold used by simplicial_set to determine small cliques
void _createSimplicialSet_()
create a new simplicial set suited for the current graph
bool setGraph(UndiGraph *graph, const NodeProperty< Size > *dom_sizes) final
sets a new graph to be triangulated
void clear() final
clears the sequence (to prepare, for instance, a new elimination sequence)
const EdgeSet & fillIns() final
in case fill-ins are provided, this function returns the fill-ins due to all the nodes eliminated so ...
bool providesFillIns() const final
indicates whether the fill-ins generated by the eliminated nodes, if needed, will be computed by the ...
double _simplicial_ratio_
the ratio used by simplicial_set for its quasi-simplicial nodes
void askFillIns(bool do_it) final
if the elimination sequence is able to compute fill-ins, we indicate whether we want this feature to ...
bool providesGraphUpdate() const final
indicates whether the elimination sequence updates by itself the graph after a node has been eliminat...
NodeId _nodeToEliminate_(const PriorityQueue< NodeId, double > &possibleNodes)
returns the best possible node to be eliminated
NodeProperty< double > _log_weights_
for each node, the weight of the clique created by the node's elimination
DefaultPartialOrderedEliminationSequenceStrategy(double theRatio=GUM_QUASI_RATIO, double theThreshold=GUM_WEIGHT_THRESHOLD)
default constructor (uses an empty graph)
DefaultPartialOrderedEliminationSequenceStrategy * copyFactory() const final
virtual copy constructor
SimplicialSet * _simplicial_set_
the simplicial set used for determining the best nodes to eliminate
NodeProperty< double > log_domain_sizes_
the log of the domain sizes of the variables/nodes
UndiGraph * graph_
the graph to be triangulated
virtual const EdgeSet & fillIns()
in case fill-ins are provided, this function returns the fill-ins due to all the nodes eliminated so ...
Generic doubly linked lists.
Definition list.h:378
bool existsNode(const NodeId id) const
returns true iff the NodeGraphPart contains the given nodeId
Exception : the element we looked for cannot be found.
bool partial_order_needed_
indicate whether a new partial ordering is necessary for the elimination
const List< NodeSet > * subsets_
the subsets constituting the partial ordering
bool setGraph(UndiGraph *graph, const NodeProperty< Size > *dom_sizes) override
sets a new graph to be triangulated
void clear() override
clears the sequence (to prepare, for instance, a new elimination sequence)
List< NodeSet >::const_iterator subset_iter_
the iterator indicating which is the current subset on which we work
PartialOrderedEliminationSequenceStrategy()
default constructor (uses an empty graph)
virtual bool setPartialOrder(const List< NodeSet > *subsets)
sets a new partial ordering constraint on the elimination sequence
NodeSet nodeset_
the nodes which can be currently eliminated
const_iterator cbegin() const
The usual unsafe begin iterator to parse the set.
Definition set_tpl.h:415
bool empty() const noexcept
Indicates whether the set is the empty set.
Definition set_tpl.h:613
void insert(const Key &k)
Inserts a new element into the set.
Definition set_tpl.h:510
void erase(const Key &k)
Erases an element from the set.
Definition set_tpl.h:553
static const const_iterator & cend() noexcept
The usual unsafe end iterator to parse the set.
Definition set_tpl.h:427
Class enabling fast retrieval of simplicial, quasi and almost simplicial nodes.
const PriorityQueue< NodeId, double > & allSimplicialNodes()
returns all the simplicial nodes
SimplicialSet(UndiGraph *graph, const NodeProperty< double > *log_domain_sizes, NodeProperty< double > *log_weights, double theRatio=GUM_QUASI_RATIO, double theThreshold=GUM_WEIGHT_THRESHOLD)
constructor. initializes the simplicial set w.r.t. a given graph
const PriorityQueue< NodeId, double > & allQuasiSimplicialNodes()
returns all the quasi simplicial nodes
const PriorityQueue< NodeId, double > & allAlmostSimplicialNodes()
returns all the almost simplicial nodes
void makeClique(const NodeId id)
adds the necessary edges so that node 'id' and its neighbors form a clique
void setFillIns(bool on_off)
sets/unset the fill-ins storage in the standard triangulation procedure
void replaceLogWeights(NodeProperty< double > *old_weigths, NodeProperty< double > *new_weights)
reassigns a new set of cliques' log weights (with the same content)
void eraseClique(const NodeId id)
removes a node and its adjacent edges from the underlying graph
const EdgeSet & fillIns() const
returns the set of all the fill-ins added to the graph so far
Base class for undirected graphs.
Definition undiGraph.h:130
An Elimination sequence algorithm that imposes a given partial ordering on the nodes elimination sequ...
#define GUM_ERROR(type, msg)
Definition exceptions.h:76
Set< Edge > EdgeSet
Some typdefs and define for shortcuts ...
Size NodeId
Type for node ids.
HashTable< NodeId, VAL > NodeProperty
Property on graph elements.
Useful macros for maths.
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
STL namespace.
Base classes for undirected graphs.