aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
ShaferShenoyLIMIDInference.h
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 /**
23  * @file
24  * @brief Implementation of an influence diagram inference algorithm based upon
25  * Shaffer-Shenoy's one for bayes net inferences
26  */
27 
28 #ifndef GUM_SHAFERSHENOY_LIMIDS_H
29 #define GUM_SHAFERSHENOY_LIMIDS_H
30 
31 #include <iostream>
32 #include <string>
33 #include <utility>
34 #include <vector>
35 
36 #include <agrum/agrum.h>
37 
38 #include <agrum/tools/core/exceptions.h>
39 #include <agrum/tools/core/list.h>
40 
41 #include <agrum/tools/graphs/DAG.h>
42 #include <agrum/tools/graphs/algorithms/triangulations/partialOrderedTriangulation.h>
43 
44 #include <agrum/tools/multidim/implementations/multiDimBucket.h>
45 #include <agrum/tools/multidim/implementations/multiDimSparse.h>
46 #include <agrum/ID/inference/tools/decisionPotential.h>
47 
48 #include <agrum/ID/inference/tools/influenceDiagramInference.h>
49 #include <agrum/tools/graphs/algorithms/triangulations/defaultTriangulation.h>
50 
51 
52 namespace gum {
53 
54  /**
55  * @class InfluenceDiagramInference influenceDiagramInference.h
56  *<agrum/ID/inference/influenceDiagramInference.h>
57  * @brief This class implements an algorithm for inference
58  * in influence diagrams based upon Shaffer-Shenoy's one for bayes net
59  *inferences
60  * @ingroup id_group
61  *
62  * The class used for the triangulation is partialOrderedTriangulation.
63  */
64  template < typename GUM_SCALAR >
65  class ShaferShenoyLIMIDInference:
66  public InfluenceDiagramInference< GUM_SCALAR > {
67  using PhiNodeProperty = NodeProperty< DecisionPotential< GUM_SCALAR > >;
68  using PsiArcProperty = ArcProperty< DecisionPotential< GUM_SCALAR > >;
69  using SetOfVars = Set< const DiscreteVariable* >;
70 
71 
72  public:
73  // ====================================================================
74  /// @name Constructor & destructor
75  // ====================================================================
76  /// @{
77 
78  /**
79  * Default constructor.
80  * @param infDiag the influence diagram we want to perform inference upon
81  */
82  explicit ShaferShenoyLIMIDInference(
83  const InfluenceDiagram< GUM_SCALAR >* infDiag);
84 
85  /**
86  * Destructor.
87  */
88  virtual ~ShaferShenoyLIMIDInference();
89 
90  const JunctionTree* junctionTree() const;
91 
92  void clear() override;
93 
94  ///@{
95  /// No forgetting rule assumption
96  void addNoForgettingAssumption(const std::vector< NodeId >& ids);
97  void addNoForgettingAssumption(const std::vector< std::string >& names);
98  bool hasNoForgettingAssumption() const;
99  ///@}
100 
101  DAG reducedGraph() const { return reduced_; };
102 
103  std::vector< NodeSet > reversePartialOrder() const;
104 
105  InfluenceDiagram< GUM_SCALAR > reducedLIMID() const;
106 
107  bool isSolvable() const;
108 
109 
110  gum::Potential< GUM_SCALAR > optimalDecision(NodeId decisionId) final;
111  gum::Potential< GUM_SCALAR >
112  optimalDecision(const std::string& decisionName) final {
113  return optimalDecision(this->influenceDiagram().idFromName(decisionName));
114  };
115 
116  /**
117  * Return the posterior probability of a node
118  *
119  * @param node
120  * @return the posterior probability
121  */
122  virtual const Potential< GUM_SCALAR >& posterior(NodeId node) final;
123  const Potential< GUM_SCALAR >& posterior(const std::string& name) final {
124  return posterior(this->influenceDiagram().idFromName(name));
125  };
126 
127  /**
128  * Return the posterior utility of a node
129  *
130  * @param node
131  * @return the posterior utility of a node
132  */
133  virtual const Potential< GUM_SCALAR >& posteriorUtility(NodeId node) final;
134  virtual const Potential< GUM_SCALAR >&
135  posteriorUtility(const std::string& name) final {
136  return posteriorUtility(this->influenceDiagram().idFromName(name));
137  };
138 
139  /**
140  * Return the pair (mean,variance) for a node
141  *
142  * @param node
143  * @return the pair (mean,variance) for a node
144  */
145  virtual std::pair< GUM_SCALAR, GUM_SCALAR > meanVar(NodeId node) final;
146  std::pair< GUM_SCALAR, GUM_SCALAR > meanVar(const std::string& name) final {
147  return meanVar(this->influenceDiagram().idFromName(name));
148  };
149 
150  /**
151  * Return the pair (mean,variance) for the total utility (MEU)
152  *
153  * @return the pair (mean,variance) for MEU
154  */
155  std::pair< GUM_SCALAR, GUM_SCALAR > MEU() final;
156 
157  protected:
158  void onStateChanged_() override;
159  void onEvidenceAdded_(NodeId id, bool isHardEvidence) override;
160  void onEvidenceErased_(NodeId id, bool isHardEvidence) override;
161  void onAllEvidenceErased_(bool contains_hard_evidence) override;
162  void onEvidenceChanged_(NodeId id, bool hasChangedSoftHard) override;
163  void onModelChanged_(const GraphicalModel* model) override;
164  void updateOutdatedStructure_() override;
165  void updateOutdatedPotentials_() override;
166  void makeInference_() override;
167 
168  /// Returns the set of non-requisite for node d
169  NodeSet nonRequisiteNodes_(NodeId d) const;
170 
171  DAG reduced_;
172  CliqueGraph reducedJunctionTree_;
173  NodeProperty< NodeId > node_to_clique_;
174  EdgeProperty< SetOfVars > varsSeparator_;
175  NodeProperty< Potential< GUM_SCALAR > > strategies_;
176  NodeProperty< DecisionPotential< GUM_SCALAR > > posteriors_;
177  NodeProperty< DecisionPotential< GUM_SCALAR > > unconditionalDecisions_;
178 
179  void createReduced_();
180  std::vector< NodeSet > reversePartialOrder_;
181  std::vector< NodeId > solvabilityOrder_;
182  std::vector< NodeId > noForgettingOrder_;
183 
184  private:
185  void completingNoForgettingAssumption__();
186  void reducingLIMID__();
187  void creatingPartialOrder__(const NodeSet& utilities);
188  void checkingSolvability__(const NodeSet& utilities);
189  void creatingJunctionTree__();
190  void findingCliqueForEachNode__(DefaultTriangulation& triangulation);
191 
192  void initializingInference_(PhiNodeProperty& phi, PsiArcProperty& psi);
193  void collectingMessage_(PhiNodeProperty& phi,
194  PsiArcProperty& psi,
195  NodeId rootClique);
196  void collectingToFollowingRoot_(PhiNodeProperty& phi,
197  PsiArcProperty& psi,
198  NodeId fromClique,
199  NodeId toClique);
200  void deciding_(PhiNodeProperty& phi, PsiArcProperty& psi, NodeId decisionNode);
201  void transmittingMessage_(PhiNodeProperty& phi,
202  PsiArcProperty& psi,
203  NodeId fromClique,
204  NodeId toClique);
205  void transmittingFinalMessage_(PhiNodeProperty& phi,
206  PsiArcProperty& psi,
207  NodeId fromClique,
208  NodeId toClique);
209  void distributingMessage_(PhiNodeProperty& phi,
210  PsiArcProperty& psi,
211  NodeId rootClique);
212  void computingPosteriors_(const PhiNodeProperty& phi,
213  const PsiArcProperty& psi);
214  DecisionPotential< double > integrating_(const PhiNodeProperty& phi,
215  const PsiArcProperty& psi,
216  NodeId clique,
217  NodeId except) const;
218  DecisionPotential< double > integrating_(const PhiNodeProperty& phi,
219  const PsiArcProperty& psi,
220  NodeId clique) const;
221  void binarizingMax_(const Potential< GUM_SCALAR >& decision,
222  const Potential< GUM_SCALAR >& proba) const;
223  };
224 } /* namespace gum */
225 
226 #include <agrum/ID/inference/ShaferShenoyLIMIDInference_tpl.h>
227 
228 #endif /* GUM_SHAFERSHENOY_LIMIDS_H */