aGrUM 3.1.1
a C++ library for (probabilistic) graphical models
structuralConstraintTabuList_inl.h
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#pragma once
42
43
51#ifndef DOXYGEN_SHOULD_SKIP_THIS
52
53namespace gum {
54
55 namespace learning {
56
58
60 INLINE void StructuralConstraintTabuList::setGraphAlone(const DiGraph& graph) {
61 // compute the hash of the graph
62 _current_graph_ = {0, 0};
63 for (const auto& arc: graph.arcs()) {
64 const auto hash_arc = _hashArc_(arc.tail(), arc.head());
65 _current_graph_.first ^= hash_arc.first;
66 _current_graph_.second ^= hash_arc.second;
67 }
68
69 // set all the elements of the _graph_tabuList_ as the current graph
71 _graph_tabuList_.clear();
73 }
74
77 return !_graph_tabuList_.existsFirst(_xorWithCurrentGraph_(_hashArc_(x, y)));
78 }
79
82 return !_graph_tabuList_.existsFirst(_xorWithCurrentGraph_(_hashArc_(x, y)));
83 }
84
87 // compute the hash of removing arc x -> y and adding arc y -> x
88 const auto hashReversal = _xorHashes_(_hashArc_(x, y), _hashArc_(y, x));
89 return !_graph_tabuList_.existsFirst(_xorWithCurrentGraph_(hashReversal));
90 }
91
94 NodeId node2,
95 NodeId node3) const {
96 const auto hashReversal12 = _xorHashes_(_hashArc_(node1, node2), _hashArc_(node2, node1));
97 const auto hashReversal13 = _xorHashes_(_hashArc_(node1, node3), _hashArc_(node3, node1));
98 const auto hashDeletion23 = _hashArc_(node2, node3);
99 const auto hashTriangle
100 = _xorHashes_(_xorHashes_(hashReversal12, hashReversal13), hashDeletion23);
101 return !_graph_tabuList_.existsFirst(_xorWithCurrentGraph_(hashTriangle));
102 }
103
106 NodeId node2,
107 NodeId node3) const {
108 const auto hashReversal23 = _xorHashes_(_hashArc_(node2, node3), _hashArc_(node3, node2));
109 const auto hashDeletion13 = _hashArc_(node1, node3);
110 const auto hashTriangle = _xorHashes_(hashReversal23, hashDeletion13);
111 return !_graph_tabuList_.existsFirst(_xorWithCurrentGraph_(hashTriangle));
112 }
113
115 INLINE bool
117 return checkArcAdditionAlone(change.node1(), change.node2());
118 }
119
121 INLINE bool
123 return checkArcDeletionAlone(change.node1(), change.node2());
124 }
125
127 INLINE bool
129 return checkArcReversalAlone(change.node1(), change.node2());
130 }
131
134 const ArcTriangleDeletion1& change) const {
135 return checkArcTriangleDeletion1Alone(change.node1(), change.node2(), change.node3());
136 }
137
140 const ArcTriangleDeletion2& change) const {
141 return checkArcTriangleDeletion2Alone(change.node1(), change.node2(), change.node3());
142 }
143
145
150 _current_graph_ = _xorWithCurrentGraph_(_hashArc_(change.node1(), change.node2()));
151
152 // The difference between the offset of the inserted graph hash and uList_offset_
153 // must always be equal to _tabuList_size_ in order to guarantee that the tabu list
154 // size is at most equal to _tabuList_size_
156 }
157
162 _current_graph_ = _xorWithCurrentGraph_(_hashArc_(change.node1(), change.node2()));
163
164 // The difference between the offset of the inserted graph hash and uList_offset_
165 // must always be equal to _tabuList_size_ in order to guarantee that the tabu list
166 // size is at most equal to _tabuList_size_
168 }
169
174 const auto hashReversal = _xorHashes_(_hashArc_(change.node1(), change.node2()),
175 _hashArc_(change.node2(), change.node1()));
177
178 // The difference between the offset of the inserted graph hash and uList_offset_
179 // must always be equal to _tabuList_size_ in order to guarantee that the tabu list
180 // size is at most equal to _tabuList_size_
182 }
183
188 const auto hashReversal12 = _xorHashes_(_hashArc_(change.node1(), change.node2()),
189 _hashArc_(change.node2(), change.node1()));
190 const auto hashReversal13 = _xorHashes_(_hashArc_(change.node1(), change.node3()),
191 _hashArc_(change.node3(), change.node1()));
192 const auto hashDeletion23 = _hashArc_(change.node2(), change.node3());
193 const auto hashTriangle
194 = _xorHashes_(_xorHashes_(hashReversal12, hashReversal13), hashDeletion23);
196
197 // The difference between the offset of the inserted graph hash and uList_offset_
198 // must always be equal to _tabuList_size_ in order to guarantee that the tabu list
199 // size is at most equal to _tabuList_size_
201 }
202
207 const auto hashReversal23 = _xorHashes_(_hashArc_(change.node2(), change.node3()),
208 _hashArc_(change.node3(), change.node2()));
209 const auto hashDeletion13 = _hashArc_(change.node1(), change.node3());
210 const auto hashTriangle = _xorHashes_(hashReversal23, hashDeletion13);
212
213 // The difference between the offset of the inserted graph hash and uList_offset_
214 // must always be equal to _tabuList_size_ in order to guarantee that the tabu list
215 // size is at most equal to _tabuList_size_
217 }
218
220
223 return false;
224 }
225
226// include all the methods applicable to the whole class hierarchy
227# define GUM_CONSTRAINT_CLASS_NAME StructuralConstraintTabuList
229# undef GUM_CONSTRAINT_CLASS_NAME
230
233 return {HashFuncConst::gold * node1 + HashFuncConst::sqrt3 * node2,
234 HashFuncConst::pi * node2 + HashFuncConst::sqrt3 * node1};
235 }
236
238 StructuralConstraintTabuList::_xorHashes_(const GraphHash& hash1,
239 const GraphHash& hash2) const {
240 return {hash1.first ^ hash2.first, hash1.second ^ hash2.second};
241 }
242
244 StructuralConstraintTabuList::_xorWithCurrentGraph_(const GraphHash& hash) const {
245 return _xorHashes_(_current_graph_, hash);
246 }
247
248 } /* namespace learning */
249
250} /* namespace gum */
251
252#endif /* DOXYGEN_SHOULD_SKIP_THIS */
The class for notifying learning algorithms of new arc additions.
The class for notifying learning algorithms of arc removals.
The class for notifying learning algorithms of arc reversals.
The graph change substituting a triangle node1->node2->node3 + node1->node3 into v-structure node2->n...
The graph change substituting a triangle node1->node2->node3 + node1->node3 into v-structure node1->n...
void modifyGraphAlone(const ArcAddition &change)
notify the constraint of a modification of the graph
bool checkArcTriangleDeletion1Alone(NodeId node1, NodeId node2, NodeId node3) const
checks whether the constraints enable to apply an ArcTriangleDeletion1
bool checkArcDeletionAlone(NodeId x, NodeId y) const
checks whether the constraints enable to remove arc (x,y)
Size _tabuList_offset_
the index of the oldest element
bool checkModificationAlone(const GraphChange &change) const
checks whether the constraints enable to perform a graph change
bool checkArcAdditionAlone(NodeId x, NodeId y) const
checks whether the constraints enable to add arc (x,y)
bool isAlwaysInvalidAlone(const GraphChange &change) const
indicates whether a change will always violate the constraint
Bijection< GraphHash, Size > _graph_tabuList_
the tabu list
void setGraphAlone(const DiGraph &graph)
sets a new graph from which we will perform checkings
bool checkArcReversalAlone(NodeId x, NodeId y) const
checks whether the constraints enable to reverse arc (x,y)
std::pair< Size, Size > GraphHash
The representation of a graph: a graph is defined by its set of arcs.
bool checkArcTriangleDeletion2Alone(NodeId node1, NodeId node2, NodeId node3) const
checks whether the constraints enable to apply an ArcTriangleDeletion2
GraphHash _xorHashes_(const GraphHash &hash1, const GraphHash &hash2) const
GraphHash _hashArc_(NodeId node1, NodeId node2) const
GraphHash _xorWithCurrentGraph_(const GraphHash &hash) const
Size NodeId
Type for node ids.
include the inlined functions if necessary
Definition CSVParser.h:55
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
static constexpr Size sqrt3
Definition hashFunc.h:105
static constexpr Size pi
Definition hashFunc.h:103
static constexpr Size gold
Definition hashFunc.h:101
the class imposing a N-sized tabu list as a structural constraints for learning algorithms