aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
structuralConstraintDAG.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 /** @file
23  * @brief the base class for structural constraints imposed by DAGs
24  *
25  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
26  */
27 #ifndef GUM_LEARNING_STRUCTURAL_CONSTRAINT_DAG_H
28 #define GUM_LEARNING_STRUCTURAL_CONSTRAINT_DAG_H
29 
30 #include <agrum/agrum.h>
31 #include <agrum/tools/graphs/algorithms/DAGCycleDetector.h>
32 #include <agrum/BN/learning/constraints/structuralConstraintDiGraph.h>
33 #include <agrum/BN/learning/constraints/structuralConstraintSetStatic.h>
34 
35 namespace gum {
36 
37  namespace learning {
38 
39  /** @class StructuralConstraintDAG
40  * @brief The base class for structural constraints imposed by DAGs
41  *
42  * This base should always be a virtual parents of the structural
43  *constraints
44  * classes. This will allow to combine different constraints into a single
45  * class
46  * @ingroup learning_group
47  */
50  public:
51  // ##########################################################################
52  /// @name Constructors / Destructors
53  // ##########################################################################
54  /// @{
55 
56  /// default constructor
58 
59  /// constructor starting with an empty graph with a given number of nodes
60  StructuralConstraintDAG(Size nb_nodes);
61 
62  /// constructor starting with a given graph
63  StructuralConstraintDAG(const DAG& graph);
64 
65  /// copy constructor
67 
68  /// move constructor
70 
71  /// destructor
72  virtual ~StructuralConstraintDAG();
73 
74  /// @}
75 
76  // ##########################################################################
77  /// @name Operators
78  // ##########################################################################
79  /// @{
80 
81  /// copy operator
83 
84  /// move operator
86 
87  /// @}
88 
89  // ##########################################################################
90  /// @name Specific Accessors / Modifiers
91  // ##########################################################################
92  /// @{
93 
94  /// sets a new graph from which we will perform checkings
95  void setGraphAlone(const DiGraph& graph);
96 
97  /// sets a new empty graph from which we will perform checkings
98  void setGraphAlone(Size nb_nodes);
99 
100  /// notify the constraint of a modification of the graph
101  /** @warning If an already existing arc is added nothing is done. In
102  * particular, no exception is raised.
103  * @throws InvalidNode exception is thrown if an arc (x,y) is added and x
104  * or y does not belong to the graph nodes
105  * @throws InvalidDirectedCycle exception is thrown if any (directed)
106  * cycle
107  * is created by the arc addition. */
108  void modifyGraphAlone(const ArcAddition& change);
109 
110  /// notify the constraint of a modification of the graph
111  /** @warning If a nonexisting arc is removed, nothing is done. In
112  * particular, no exception is raised. */
113  void modifyGraphAlone(const ArcDeletion& change);
114 
115  /// notify the constraint of a modification of the graph
116  /** @warning If an already existing arc is added, or if a nonexisting arc
117  * is removed, nothing is done. In particular, no exception is raised.
118  * @throws InvalidNode exception is thrown if at least one extremity of
119  * the arc does not belong to the graph nodes
120  * @throws InvalidDirectedCycle exception is thrown if any (directed)
121  * cycle
122  * is created by the arc reversal. */
123  void modifyGraphAlone(const ArcReversal& change);
124 
125  /// notify the constraint of a modification of the graph
126  /** @warning If an already existing arc is added, or if a nonexisting arc
127  * is removed, nothing is done. In particular, no exception is raised.
128  * @throws InvalidNode exception is thrown if an arc (x,y) is added and x
129  * or y does not belong to the graph nodes
130  * @throws InvalidDirectedCycle exception is thrown if any (directed)
131  * cycle
132  * is created by an arc addition or reversal. */
133  void modifyGraphAlone(const GraphChange& change);
134 
135  /// indicates whether a change will always violate the constraint
136  /** Some learning algorithms need examine several times whether a given
137  * graph change can be applied. For instance, the first time arc (X,Y)
138  * addition is considered, the learning algorithm may discard this change
139  * because it violates the structural constraint (e.g., if the latter
140  * enforces a DAG structure, this arc addition might induce a directed
141  * cycle), but, later on, other arc removal may induce that the arc
142  * addition
143  * is now possible. Such change is thus not always invalid. Conversely,
144  * there are changes that can be discarded once and for all. For instance,
145  * in a 2TBN structure, it is always impossible to add a backward-time
146  * arc.
147  * Such graph changes are always invalid and are therefore tagged as such
148  * by the isAlwaysInvalid method. */
149  bool isAlwaysInvalidAlone(const GraphChange& change) const;
150 
151  /// checks whether the constraints enable to add arc (x,y)
152  /** an arc can be added if and only if its extremal nodes belong to the
153  * graph and the arc does not already exist and would not create a cycle
154  */
155  bool checkArcAdditionAlone(NodeId x, NodeId y) const;
156 
157  /// checks whether the constraints enable to remove arc (x,y)
158  bool checkArcDeletionAlone(NodeId x, NodeId y) const;
159 
160  /// checks whether the constraints enable to reverse arc (x,y)
161  /** An arc (x,y) can be reversed if and only if it exists and, after
162  * deleting it, the addition of arc (y,x) does not induce a
163  * directed cycle. */
164  bool checkArcReversalAlone(NodeId x, NodeId y) const;
165 
166  /// checks whether the constraints enable to add an arc
167  /** an arc can be added if and only if its extremal nodes belong to the
168  * graph and the arc does not already exist. */
169  bool checkModificationAlone(const ArcAddition& change) const;
170 
171  /// checks whether the constraints enable to remove an arc
172  /** an arc can be removed if and only if the arc exists. */
173  bool checkModificationAlone(const ArcDeletion& change) const;
174 
175  /// checks whether the constraints enable to reverse an arc
176  /** An arc can be reversed if, after deleting arc (x,y), the addition of
177  * arc (y,x) does not induce a directed cycle. */
178  bool checkModificationAlone(const ArcReversal& change) const;
179 
180  /// checks whether the constraints enable to perform a graph change
181  /** an arc can be added if and only if its extremal nodes belong to the
182  * graph and the arc does not already exist and would not create a cycle.
183  * An arc can be removed if and only if the arc exists.
184  * An arc can be reversed if, after deleting arc (x,y), the addition of
185  * arc (y,x) does not induce a directed cycle. */
186  bool checkModificationAlone(const GraphChange& change) const;
187 
188  /// sets a new graph from which we will perform checkings
189  void setGraph(const DAG& graph);
190 
191  /// sets a new empty graph from which we will perform checkings
192  void setGraph(Size nb_nodes);
193 
194  /// @}
195 
196 #ifndef DOXYGEN_SHOULD_SKIP_THIS
197 // include the set of methods that enable the structural constraint to
198 // be standalone, i.e., that it needs not be included into a
199 // StructuralConstraintSetStatic to be used by learning algorithms
200 # define GUM_CONSTRAINT_CLASS_NAME StructuralConstraintDAG
201 # include <agrum/BN/learning/constraints/structuralConstraintPatternHeader.h>
202 # undef GUM_CONSTRAINT_CLASS_NAME
203 #endif // DOXYGEN_SHOULD_SKIP_THIS
204 
205  protected:
206  /// the cycle detector used to check quickly graph modifications
208  };
209 
210  } /* namespace learning */
211 
212 } /* namespace gum */
213 
214 /// include the inlined functions if necessary
215 #ifndef GUM_NO_INLINE
216 # include <agrum/BN/learning/constraints/structuralConstraintDAG_inl.h>
217 #endif /* GUM_NO_INLINE */
218 
219 #endif /* GUM_LEARNING_STRUCTURAL_CONSTRAINT_DAG_H */
void setGraph(const DAG &graph)
sets a new graph from which we will perform checkings
StructuralConstraintDAG(const StructuralConstraintDAG &from)
copy constructor
StructuralConstraintDAG(const DAG &graph)
constructor starting with a given graph
StructuralConstraintDAG(StructuralConstraintDAG &&from)
move constructor
StructuralConstraintDAG & operator=(StructuralConstraintDAG &&from)
move operator
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
void setGraphAlone(const DiGraph &graph)
sets a new graph from which we will perform checkings
void setGraphAlone(Size nb_nodes)
sets a new empty graph from which we will perform checkings
bool checkArcAdditionAlone(NodeId x, NodeId y) const
checks whether the constraints enable to add arc (x,y)
StructuralConstraintDAG(Size nb_nodes)
constructor starting with an empty graph with a given number of nodes
bool isAlwaysInvalidAlone(const GraphChange &change) const
indicates whether a change will always violate the constraint
bool checkArcReversalAlone(NodeId x, NodeId y) const
checks whether the constraints enable to reverse arc (x,y)
bool checkModificationAlone(const GraphChange &change) const
checks whether the constraints enable to perform a graph change
bool checkArcDeletionAlone(NodeId x, NodeId y) const
checks whether the constraints enable to remove arc (x,y)
DAGCycleDetector _DAG_cycle_detector_
the cycle detector used to check quickly graph modifications
void modifyGraphAlone(const GraphChange &change)
notify the constraint of a modification of the graph
Database(const std::string &filename, const BayesNet< GUM_SCALAR > &bn, const std::vector< std::string > &missing_symbols)
StructuralConstraintDAG & operator=(const StructuralConstraintDAG &from)
copy operator
void setGraph(Size nb_nodes)
sets a new empty graph from which we will perform checkings
The base class for structural constraints imposed by DAGs.