aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
influenceDiagram.h
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 /**
23  * @file
24  * @brief Class representing Influence Diagrams
25  *
26  * @author Pierre-Henri WUILLEMIN(@LIP6) and Jean-Christophe MAGNAN and Christophe
27  * GONZALES(@AMU)
28  *
29  */
30 
31 #ifndef GUM_INF_DIAG_H
32 #define GUM_INF_DIAG_H
33 
34 #include <string>
35 #include <utility>
36 
37 #include <agrum/agrum.h>
38 
39 #include <agrum/tools/core/hashTable.h>
40 #include <agrum/tools/graphicalModels/DAGmodel.h>
41 #include <agrum/tools/multidim/potential.h>
42 
43 namespace gum {
44 
45  /**
46  * @class InfluenceDiagram
47  * @headerfile influenceDiagram.h <agrum/ID/influenceDiagram.h>
48  * @brief Class representing an Influence Diagram
49  * @ingroup InfluenceDiagram_group
50  *
51  */
52  template < typename GUM_SCALAR >
53  class InfluenceDiagram: public DAGmodel {
54  // friend class InfluenceDiagramFactory<GUM_SCALAR>;
55  public:
56  /**
57  * Create an Influence Diagram with a dot-like syntax which specifies:
58  * - the structure "a->*b->$c;b->d<-*e;".
59  * - the prefix of a variable can be :
60  * - nothing : chance node (a,d)
61  * - * : decision node (*b)
62  * - $ : utility node ($c) *
63  * - the type of the chance or decision variables with different syntax:
64  * + by default, a variable is a gum::RangeVariable using the default
65  * domainSize (second argument)
66  * + with "a[10]", the variable is a gum::RangeVariable using 10 as
67  * domainSize (from 0 to 9)
68  * + with "a[3,7]", the variable is a gum::RangeVariable using a domainSize
69  * from 3 to 7
70  * + with "a[1,3.14,5,6.2]", the variable is a gum::DiscretizedVariable
71  * using the given ticks (at least 3 values)
72  * + with "a{top|middle|bottom}", the variable is a gum::LabelizedVariable
73  * using the given labels.
74  *
75  * Note that if the dot-like string contains such a specification more than
76  * once for a variable, the first specification will be used.
77  *
78  * @param dotlike the string containing the specification
79  * @param domainSize the default domain size for chance and decision variables
80  * @return the resulting influence diagram
81  */
82  static InfluenceDiagram< GUM_SCALAR > fastPrototype(const std::string& dotlike,
83  Size domainSize = 2);
84 
85  // ===========================================================================
86  /// @name Constructors / Destructors
87  // ===========================================================================
88  /// @{
89 
90  /**
91  * Default constructor.
92  */
94 
95  /**
96  * Destructor.
97  */
99 
100  /**
101  * Copy Constructor
102  */
103  InfluenceDiagram(const InfluenceDiagram< GUM_SCALAR >& source);
104 
105  /**
106  * Copy Operator
107  */
108  InfluenceDiagram< GUM_SCALAR >& operator=(const InfluenceDiagram< GUM_SCALAR >& source);
109 
110  /// @}
111 
112  /// @return Returns a dot representation of this Influence Diagram.
113  std::string toDot() const;
114 
115  /// @return Returns a string representation of this Influence Diagram.
116  std::string toString() const;
117 
118  void clear();
119 
120  // ===========================================================================
121  /// @name Variable manipulation methods.
122  // ===========================================================================
123  /// @{
124 
125  /**
126  * Returns the CPT of a potential variable.
127  * @throw NotFound If no variable's id matches varId.
128  */
129  virtual const Potential< GUM_SCALAR >& cpt(NodeId varId) const;
130  virtual const Potential< GUM_SCALAR >& cpt(std::string name) const final {
131  return cpt(idFromName(name));
132  };
133 
134  /**
135  * Returns the utility table of a utility node.
136  * @throw NotFound If no variable's id matches varId.
137  */
138  virtual const Potential< GUM_SCALAR >& utility(NodeId varId) const;
139  virtual const Potential< GUM_SCALAR >& utility(std::string name) const final {
140  return utility(idFromName(name));
141  };
142 
143  /**
144  * Returns a constant reference to the VariableNodeMap of this Influence
145  * Diagram
146  */
147  const VariableNodeMap& variableNodeMap() const final;
148 
149  /**
150  * Returns true if node is a utility one
151  */
152  bool isUtilityNode(NodeId varId) const;
153  bool isUtilityNode(const std::string& name) const { return isUtilityNode(idFromName(name)); };
154  /**
155  * Returns true if node is a decision one
156  */
157  bool isDecisionNode(NodeId varId) const;
158  bool isDecisionNode(const std::string& name) const { return isDecisionNode(idFromName(name)); };
159 
160  /**
161  * Returns true if node is a chance one
162  */
163  bool isChanceNode(NodeId varId) const;
164  bool isChanceNode(const std::string& name) const { return isChanceNode(idFromName(name)); };
165  /**
166  * Returns the number of utility nodes
167  */
168  Size utilityNodeSize() const;
169 
170  /**
171  * Returns the number of chance nodes
172  */
173  Size chanceNodeSize() const;
174 
175  /**
176  * Returns the number of decision nodes
177  */
178  Size decisionNodeSize() const;
179 
180  /**
181  * Returns a constant reference over a variable given it's node id.
182  * @throw NotFound If no variable's id matches varId.
183  */
184  const DiscreteVariable& variable(NodeId id) const final;
185 
186  /**
187  * Return id node from discrete var pointer.
188  * @throw NotFound If no variable matches var.
189  */
190  NodeId nodeId(const DiscreteVariable& var) const final;
191 
192  /// Getter by name
193  /// @throw NotFound if no such name exists in the graph.
194  NodeId idFromName(const std::string& name) const final;
195 
196  /// Getter by name
197  /// @throw NotFound if no such name exists in the graph.
198  const DiscreteVariable& variableFromName(const std::string& name) const final;
199 
200  /**
201  * Add a chance variable, it's associate node and it's CPT. The id of the
202  *new
203  * variable is automatically generated.
204  *
205  * The implementation of the Potential is by default a MultiDimArray.
206  *
207  * @param variable The variable added by copy.
208  * @param id The chosen id. If 0, the NodeGraphPart will choose.
209  * @warning give an id (not 0) should be reserved for rare and specific
210  *situations !!!
211  * @return the id of the added variable.
212  * @throws DuplicateElement if id(<>0) is already used
213  */
215 
216  /**
217  * Add a chance variable, it's associate node and it's CPT. The id of the new
218  * variable is automatically generated.
219  *
220  * The implementation of the Potential is by default a MultiDimArray.
221  *
222  * @param variable The variable added by copy.
223  * @param id The chosen id. If 0, the NodeGraphPart will choose.
224  * @warning give an id (not 0) should be reserved for rare and specific
225  *situations
226  *!!!
227  * @return the id of the added variable.
228  * @throws DuplicateElement if id(<>0) is already used
229  */
231 
232  /**
233  * Add a utility variable, it's associate node and it's UT. The id of the
234  *new variable is automatically generated.
235  *
236  * The implementation of the Utility is by default a MultiDimArray.
237  *
238  * @param variable The variable added by copy.
239  * @param id The chosen id. If 0, the NodeGraphPart will choose.
240  * @warning give an id (not 0) should be reserved for rare and specific
241  *situations !!!
242  * @return the id of the added variable.
243  * @throw InvalidArgument If variable has more than one label
244  * @throws DuplicateElement if id(<>0) is already used
245  */
247 
248  /**
249  * Add a decision variable. The id of the new
250  * variable is automatically generated.
251  *
252  * @param variable The variable added by copy.
253  * @param id The chosen id. If 0, the NodeGraphPart will choose.
254  * @warning give an id (not 0) should be reserved for rare and specific
255  *situations !!!
256  * @return the id of the added variable.
257  * @throws DuplicateElement if id(<>0) is already used
258  */
260 
261  /**
262  * Add a chance variable, it's associate node and it's CPT. The id of the
263  *new
264  * variable is automatically generated.
265  *
266  * @param variable The variable added by copy.
267  * @param aContent The content used for the variable potential.
268  * @param id The chosen id. If 0, the NodeGraphPart will choose.
269  * @warning give an id (not 0) should be reserved for rare and specific
270  *situations !!!
271  * @return the id of the added variable.
272  * @throws DuplicateElement if id(<>0) is already used
273  */
276  NodeId id = 0);
277 
278  /**
279  * Add a chance variable, it's associate node and it's CPT. The id of the
280  *new
281  * variable is automatically generated.
282  *
283  * @param variable The variable added by copy.
284  * @param aContent The content used for the variable utility.
285  * @param id The chosen id. If 0, the NodeGraphPart will choose.
286  * @warning give an id (not 0) should be reserved for rare and specific
287  *situations !!!
288  * @throw InvalidArgument If variable has more than one label
289  * @throws DuplicateElement if id(<>0) is already used
290  */
293  NodeId id = 0);
294 
295  /**
296  * Erase a Variable from the network and remove the variable from
297  * all his children.
298  * If no variable matches the id, then nothing is done.
299  *
300  * @param id The id of the variable to erase.
301  */
302  void erase(NodeId id);
303  void erase(const std::string& name) { erase(idFromName(name)); };
304 
305  /**
306  * Erase a Variable from the network and remove the variable from
307  * all his children.
308  * If no variable matches, then nothing is done.
309  *
310  * @param var The reference on the variable to remove.
311  */
312  void erase(const DiscreteVariable& var);
313 
314  /** we allow the user to change the name of a variable
315  * @throws DuplicateLabel if this name already exists
316  * @throws NotFound Raised if no nodes matches id.
317  */
318  void changeVariableName(NodeId id, const std::string& new_name);
319  void changeVariableName(const std::string& name, const std::string& new_name) {
320  changeVariableName(idFromName(name), new_name);
321  }
322 
323  /// @}
324  // ===========================================================================
325  /// @name Arc manipulation methods.
326  // ===========================================================================
327  /// @{
328 
329  /**
330  * Add an arc in the ID, and update diagram's potential nodes cpt if
331  *necessary.
332  *
333  * @param head and
334  * @param tail as NodeId
335  * @throw InvalidEdge If arc.tail and/or arc.head are not in the ID.
336  * @throw InvalidEdge if tail is a utility node
337  */
338  void addArc(NodeId tail, NodeId head);
339  void addArc(const std::string& tail, const std::string& head) {
340  addArc(idFromName(tail), idFromName(head));
341  }
342 
343  /**
344  * Removes an arc in the ID, and update diagram's potential nodes cpt if
345  *necessary.
346  *
347  * If (tail, head) doesn't exist, the nothing happens.
348  * @param arc The arc removed.
349  */
350  void eraseArc(const Arc& arc);
351 
352  /**
353  * Removes an arc in the ID, and update diagram's potential nodes cpt if
354  *necessary.
355  *
356  * If (tail, head) doesn't exist, the nothing happens.
357  * @param head and
358  * @param tail as NodeId
359  */
360  void eraseArc(NodeId tail, NodeId head);
361  void eraseArc(const std::string& tail, const std::string& head) {
362  eraseArc(idFromName(tail), idFromName(head));
363  }
364 
365  /// @}
366 
367  // ===========================================================================
368  /// @name Decisions methods
369  // ===========================================================================
370  /// @{
371 
372  /**
373  * True if a directed path exist with all decision nodes
374  */
375  bool decisionOrderExists() const;
376 
377  /**
378  * Returns the temporal Graph
379  */
380  gum::DAG* getDecisionGraph() const;
381 
382  /**
383  * Returns the sequence of decision nodes in the directed path
384  * @throw NotFound if such a path does not exist
385  */
386  std::vector< NodeId > decisionOrder() const;
387 
388  /**
389  * Returns true if a path exists between two nodes
390  */
391  bool existsPathBetween(NodeId src, NodeId dest) const;
392  bool existsPathBetween(const std::string& src, const std::string& dest) const {
393  return existsPathBetween(idFromName(src), idFromName(dest));
394  }
395 
396  /**
397  * Returns partial temporal ordering
398  * @throw NotFound if such a sequence does not exist
399  */
400  const List< NodeSet >& getPartialTemporalOrder(bool clear = true) const;
401 
402  /// @}
403 
404  protected:
405  /// Returns the moral graph of this InfluenceDiagram.
406  virtual void moralGraph_(UndiGraph& graph) const;
407 
408  /**
409  * Removing ancient table
410  */
411  void removeTables_();
412 
413  /**
414  * Copying tables from another influence diagram
415  */
416  void copyStructureAndTables_(const InfluenceDiagram< GUM_SCALAR >& IDsource);
417 
418  /**
419  * Add a node
420  */
422 
423  /**
424  * Returns the list of children decision for a given nodeId
425  */
427 
428  private:
429  /// Mapping between id and variable
431 
432  /// Mapping between potential variable's id and their CPT
434  /// Mapping between utility variable's id and their utility table
436 
437  /// The temporal order
439  };
440 
441 } /* namespace gum */
442 
443 #include <agrum/ID/influenceDiagram_tpl.h>
444 
445 #endif /* GUM_INF_DIAG_H */
static InfluenceDiagram< GUM_SCALAR > fastPrototype(const std::string &dotlike, Size domainSize=2)
Create an Influence Diagram with a dot-like syntax which specifies:
void addArc(NodeId tail, NodeId head)
Add an arc in the ID, and update diagram&#39;s potential nodes cpt if necessary.
NodeId idFromName(const std::string &name) const final
Getter by name.
bool isChanceNode(NodeId varId) const
Returns true if node is a chance one.
void erase(NodeId id)
Erase a Variable from the network and remove the variable from all his children.
NodeId addChanceNode(const DiscreteVariable &variable, NodeId id=0)
Add a chance variable, it&#39;s associate node and it&#39;s CPT.
bool existsPathBetween(NodeId src, NodeId dest) const
Returns true if a path exists between two nodes.
std::string toString() const
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
NodeId nodeId(const DiscreteVariable &var) const final
Return id node from discrete var pointer.
gum::DAG * getDecisionGraph() const
Returns the temporal Graph.
void removeTables_()
Removing ancient table.
bool existsPathBetween(const std::string &src, const std::string &dest) const
True if a directed path exist with all decision nodes.
NodeId addChanceNode(const DiscreteVariable &variable, MultiDimImplementation< GUM_SCALAR > *aContent, NodeId id=0)
Add a chance variable, it&#39;s associate node and it&#39;s CPT.
std::vector< NodeId > decisionOrder() const
Returns the sequence of decision nodes in the directed path.
Size decisionNodeSize() const
Returns the number of decision nodes.
virtual const Potential< GUM_SCALAR > & utility(NodeId varId) const
Returns the utility table of a utility node.
void changeVariableName(NodeId id, const std::string &new_name)
we allow the user to change the name of a variable
Size chanceNodeSize() const
Returns the number of chance nodes.
Size utilityNodeSize() const
Returns the number of utility nodes.
bool isChanceNode(const std::string &name) const
Returns the CPT of a potential variable.
void addArc(const std::string &tail, const std::string &head)
Add an arc in the ID, and update diagram&#39;s potential nodes cpt if necessary.
const DiscreteVariable & variableFromName(const std::string &name) const final
Getter by name.
virtual const Potential< GUM_SCALAR > & utility(std::string name) const final
Returns the CPT of a potential variable.
std::string toDot() const
void eraseArc(NodeId tail, NodeId head)
Removes an arc in the ID, and update diagram&#39;s potential nodes cpt if necessary.
const List< NodeSet > & getPartialTemporalOrder(bool clear=true) const
Returns partial temporal ordering.
NodeProperty< Potential< GUM_SCALAR > *> _utilityMap_
Mapping between utility variable&#39;s id and their utility table.
bool isDecisionNode(NodeId varId) const
Returns true if node is a decision one.
List< NodeSet > _temporalOrder_
The temporal order.
bool isUtilityNode(NodeId varId) const
Returns true if node is a utility one.
VariableNodeMap _variableMap_
Mapping between id and variable.
NodeId addNode_(const DiscreteVariable &variableType, NodeId DesiredId)
Add a node.
void changeVariableName(const std::string &name, const std::string &new_name)
Returns the CPT of a potential variable.
NodeId addUtilityNode(const DiscreteVariable &variable, MultiDimImplementation< GUM_SCALAR > *aContent, NodeId id=0)
Add a chance variable, it&#39;s associate node and it&#39;s CPT.
void eraseArc(const std::string &tail, const std::string &head)
Add an arc in the ID, and update diagram&#39;s potential nodes cpt if necessary.
bool decisionOrderExists() const
True if a directed path exist with all decision nodes.
Sequence< NodeId > getChildrenDecision_(NodeId parentDecision) const
Returns the list of children decision for a given nodeId.
void erase(const std::string &name)
Returns the CPT of a potential variable.
InfluenceDiagram< GUM_SCALAR > & operator=(const InfluenceDiagram< GUM_SCALAR > &source)
Copy Operator.
void copyStructureAndTables_(const InfluenceDiagram< GUM_SCALAR > &IDsource)
Copying tables from another influence diagram.
virtual void moralGraph_(UndiGraph &graph) const
Returns the moral graph of this InfluenceDiagram.
void erase(const DiscreteVariable &var)
Erase a Variable from the network and remove the variable from all his children.
void eraseArc(const Arc &arc)
Removes an arc in the ID, and update diagram&#39;s potential nodes cpt if necessary.
bool isUtilityNode(const std::string &name) const
Returns the CPT of a potential variable.
NodeId addUtilityNode(const DiscreteVariable &variable, NodeId id=0)
Add a utility variable, it&#39;s associate node and it&#39;s UT.
InfluenceDiagram()
Default constructor.
NodeId add(const DiscreteVariable &variable, NodeId id=0)
Add a chance variable, it&#39;s associate node and it&#39;s CPT.
InfluenceDiagram(const InfluenceDiagram< GUM_SCALAR > &source)
Copy Constructor.
virtual const Potential< GUM_SCALAR > & cpt(std::string name) const final
Returns the CPT of a potential variable.
NodeId addDecisionNode(const DiscreteVariable &variable, NodeId id=0)
Add a decision variable.
~InfluenceDiagram() override
Destructor.
const DiscreteVariable & variable(NodeId id) const final
Returns a constant reference over a variable given it&#39;s node id.
const VariableNodeMap & variableNodeMap() const final
Returns a constant reference to the VariableNodeMap of this Influence Diagram.
virtual const Potential< GUM_SCALAR > & cpt(NodeId varId) const
Returns the CPT of a potential variable.
bool isDecisionNode(const std::string &name) const
Returns the CPT of a potential variable.