aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
defaultJunctionTreeStrategy.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 algorithms producing a junction given the elimination tree
24  * produced by the triangulation algorithm
25  *
26  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
27  */
28 
29 #include <numeric>
30 
31 #include <agrum/agrum.h>
32 #include <agrum/tools/graphs/algorithms/triangulations/junctionTreeStrategies/defaultJunctionTreeStrategy.h>
33 #include <agrum/tools/graphs/algorithms/triangulations/staticTriangulation.h>
34 
35 namespace gum {
36 
37  // default constructor
39  // for debugging purposes
41  }
42 
43  // copy constructor
50  // for debugging purposes
52  }
53 
54  // move constructor
61  // for debugging purposes
63  }
64 
65  // destructor
67  // for debugging purposes
69  }
70 
71  // clone factory
73  return new DefaultJunctionTreeStrategy;
74  }
75 
76  // virtual copy constructor
79  if (tr == nullptr) {
80  return new DefaultJunctionTreeStrategy(*this);
81  } else {
82  // here, we need to assign new triangulation "tr" to the new strategy
83 
84  // if there was already a triangulation associated with the current
85  // strategy, 2 cases can obtain:
86  // 1/ both triangulation__ and tr point toward the same graph to be
87  // triangulated. In this case, no need to recompute anything
88  // 2/ they point toward different graphs. Then, we must indicate that
89  // the new strategy has not computed anything yet
90  if ((triangulation_ != nullptr)
92  auto new_strategy = new DefaultJunctionTreeStrategy(*this); // case 1/
94  return new_strategy;
95  } else { // case 2/
98  return new_strategy;
99  }
100  }
101  }
102 
103  // indicates whether the junction tree strategy needs fill-ins to work
104  // properly
105  bool DefaultJunctionTreeStrategy::requiresFillIns() const { return false; }
106 
107  // assign the triangulation to the junction tree strategy
109  clear();
110  triangulation_ = tr;
111  }
112 
113  // returns, for each node, the clique which was created by its deletion
115  // compute the junction tree only if it does not already exist
117 
119  }
120 
121  // returns the Id of the clique created by the elimination of a given
122  // node during the triangulation process */
124  // compute the junction tree only if it does not already exist
126 
128  }
129 
130  // returns the junction tree asked by the triangulation
132  // compute the junction tree only if it does not already exist
134 
135  return junction_tree__;
136  }
137 
138  // resets the current junction tree strategy data structures
140  has_junction_tree__ = false;
143  }
144 
145  // computes a junction tree from an elimination tree
147  // if no triangulation is assigned to the strategy, we cannot compute
148  // the junction tree, so raise an exception
149  if (triangulation_ == nullptr)
151  "No triangulation has been assigned to "
152  "the DefaultJunctionTreeStrategy");
153 
154  // copy the elimination tree into the junction tree
156 
157  // mark all the edges of the junction tree to false
159 
160  // create a vector indicating by which clique a given clique has been
161  // substituted during the transformation from the elimination tree to the
162  // junction tree. Assume that clique J of the elmination tree has been
163  // substituted by clique K of the elimination tree, and that clique J
164  // (resp. K) was the jth (resp. kth) one created during the triangulation
165  // process. Then, in the vector below, substitution[j] = k.
167 
168  auto size = elim_order.size();
171 
172  // for all cliques C_i, from the last one created to the first one, check
173  // if there exists a parent C_j (a neighbor created before C_i) such that
174  // |C_j| = |C_i| + 1 and such that the edge is not marked. In this case,
175  // this means that C_j contains C_i. Hence, we should remove C_i, and link
176  // all of its neighbors to C_j. These links will be marked to true as no
177  // such neighbor can be included in C_j (and conversely).
178  if (size > 0) {
179  for (auto i = size; i >= 1; --i) {
180  const NodeId C_i = NodeId(i - 1);
181  const auto card_C_i_plus_1 = junction_tree__.clique(C_i).size() + 1;
182 
183  // search for C_j such that |C_j| = [C_i| + 1
184  NodeId C_j = C_i;
185 
186  for (const auto C_jj: junction_tree__.neighbours(C_i))
187  if ((C_i > C_jj) && !mark[Edge(C_jj, C_i)]
189  // ok, here we found a parent such that |C_jj| = [C_i| + 1
190  C_j = C_jj;
192  break;
193  }
194 
195  // if we found a C_j, link the neighbors of C_i to C_j
196  if (C_j != C_i) {
197  for (const auto nei: junction_tree__.neighbours(C_i)) {
199  mark.insert(Edge(C_j, nei), true);
200  }
201 
202  // remove C_i
203  substitution[C_i] = C_j;
205  }
206  }
207  }
208 
209  // compute the transitive closure of vector substitution
210  for (std::size_t i = 0; i < size; ++i)
212 
213  // using the transitive closure of vector substitution, compute for each
214  // node the clique of the junction tree that was created by its
215  // elimination during the triangulation
216  for (NodeId i = NodeId(0); i < size; ++i) {
218  }
219 
220  has_junction_tree__ = true;
221  }
222 
223 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669