aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
graphChangesGenerator4K2_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2025 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-2025 *
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#pragma once
41
42
49#ifndef DOXYGEN_SHOULD_SKIP_THIS
50
51namespace gum {
52
53 namespace learning {
54
56 template < typename STRUCT_CONSTRAINT >
58 STRUCT_CONSTRAINT& constraint) : constraint_(&constraint) {
59 GUM_CONSTRUCTOR(GraphChangesGenerator4K2);
60 }
61
63 template < typename STRUCT_CONSTRAINT >
64 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::GraphChangesGenerator4K2(
65 const GraphChangesGenerator4K2& from) :
66 graph_(from.graph_), constraint_(from.constraint_), order_(from.order_),
67 legal_changes_(from.legal_changes_), _max_threads_number_(from._max_threads_number_) {
68 GUM_CONS_CPY(GraphChangesGenerator4K2);
69 }
70
72 template < typename STRUCT_CONSTRAINT >
73 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::GraphChangesGenerator4K2(
74 GraphChangesGenerator4K2&& from) :
75 graph_(std::move(from.graph_)), constraint_(from.constraint_),
76 order_(std::move(from.order_)), legal_changes_(std::move(from.legal_changes_)),
77 _max_threads_number_(from._max_threads_number_) {
78 GUM_CONS_MOV(GraphChangesGenerator4K2);
79 }
80
82 template < typename STRUCT_CONSTRAINT >
83 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::~GraphChangesGenerator4K2() {
84 GUM_DESTRUCTOR(GraphChangesGenerator4K2);
85 }
86
88 template < typename STRUCT_CONSTRAINT >
89 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >&
90 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::operator=(
91 const GraphChangesGenerator4K2< STRUCT_CONSTRAINT >& from) {
92 if (this != &from) {
93 graph_ = from.graph_;
94 constraint_ = from.constraint_;
95 order_ = from.order_;
96 legal_changes_ = from.legal_changes_;
97 _max_threads_number_ = from._max_threads_number_;
98 }
99 return *this;
100 }
101
103 template < typename STRUCT_CONSTRAINT >
104 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >&
105 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::operator=(
106 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >&& from) {
107 if (this != &from) {
108 graph_ = std::move(from.graph_);
109 constraint_ = std::move(from.constraint_);
110 order_ = std::move(from.order_);
111 legal_changes_ = std::move(from.legal_changes_);
112 _max_threads_number_ = from._max_threads_number_;
113 }
114 return *this;
115 }
116
118 template < typename STRUCT_CONSTRAINT >
119 void GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::createChanges_() {
120 legal_changes_.clear();
121
122 // for all the pairs of nodes, consider adding, reverse and removing arcs
123 const Size nb_threads = _max_threads_number_;
124 std::vector< Set< GraphChange > > legal_changes(nb_threads);
125
126 // create the lambda that will be used to fill the legal changes
127 auto threadedLegalSet = [this, &legal_changes](const std::size_t this_thread,
128 const std::size_t nb_threads) -> void {
129 for (Idx i = 0, j = 0; j < this->order_.size(); i = (i + 1) % nb_threads, ++j) {
130 if (i == this_thread) {
131 for (Idx k = j + 1; k < this->order_.size(); ++k) {
132 // try arc additions
133 ArcAddition arc_add(order_[j], order_[k]);
134 if (!this->constraint_->isAlwaysInvalid(arc_add)) {
135 legal_changes[this_thread].insert(std::move(arc_add));
136 }
137 }
138 }
139 }
140 };
141
142 // launch the threads
143 ThreadExecutor::execute(nb_threads, threadedLegalSet);
144
145 // now store the changes into the protected vectors of the
146 // GraphChangesGenerator4K2
147 for (const auto& changes: legal_changes) {
148 for (const auto& change: changes) {
149 legal_changes_.insert(std::move(change));
150 }
151 }
152 }
153
155 template < typename STRUCT_CONSTRAINT >
156 void GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::setGraph(const DiGraph& graph) {
157 // sets the current graph
158 graph_ = graph;
159
160 // check that all the nodes of the graph belong to the sequence.
161 // If some are missing, add them in increasing order into the sequence.
162 // If some element of order_ do not belong to the graph, remove them
163 for (auto node = order_.beginSafe(); node != order_.endSafe(); ++node) {
164 if (!graph.exists(*node)) { order_.erase(node); }
165 }
166 for (const auto node: graph) {
167 if (!order_.exists(node)) { order_.insert(node); }
168 }
169
170 // generate the set of all changes
171 createChanges_();
172 }
173
175 template < typename STRUCT_CONSTRAINT >
176 INLINE void
177 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::setOrder(const Sequence< NodeId >& order) {
178 order_ = order;
179 }
180
182 template < typename STRUCT_CONSTRAINT >
183 INLINE void GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::setOrder(
184 const std::vector< NodeId >& order) {
185 order_.clear();
186 for (const auto node: order) {
187 order_.insert(node);
188 }
189 }
190
192 template < typename STRUCT_CONSTRAINT >
193 INLINE void GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::clearChanges() noexcept {
194 legal_changes_.clear();
195 }
196
198 template < typename STRUCT_CONSTRAINT >
199 INLINE typename GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::iterator
200 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::begin() const {
201 return legal_changes_.cbegin();
202 }
203
205 template < typename STRUCT_CONSTRAINT >
206 INLINE const typename GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::iterator&
207 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::end() const {
208 return legal_changes_.cend();
209 }
210
212 template < typename STRUCT_CONSTRAINT >
213 INLINE void
214 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::modifyGraph(const ArcAddition& change) {}
215
217 template < typename STRUCT_CONSTRAINT >
218 INLINE void
219 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::modifyGraph(const ArcDeletion& change) {}
220
222 template < typename STRUCT_CONSTRAINT >
223 INLINE void
224 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::modifyGraph(const ArcReversal& change) {}
225
227 template < typename STRUCT_CONSTRAINT >
228 INLINE void
229 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::modifyGraph(const GraphChange& change) {}
230
232 template < typename STRUCT_CONSTRAINT >
233 INLINE void GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::notifyGetCompleted() {
234 if (legal_changes_.size()) legal_changes_.clear();
235 }
236
238 template < typename STRUCT_CONSTRAINT >
239 INLINE void GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::setMaxNbThreads(Size nb) noexcept {
240 if (nb == 0) nb = gum::getNumberOfThreads();
241 _max_threads_number_ = nb;
242 }
243
245 template < typename STRUCT_CONSTRAINT >
246 INLINE STRUCT_CONSTRAINT&
247 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::constraint() const noexcept {
248 return *constraint_;
249 }
250
251 } /* namespace learning */
252
253} /* namespace gum */
254
255#endif /* DOXYGEN_SHOULD_SKIP_THIS */
GraphChangesGenerator4K2(STRUCT_CONSTRAINT &constraint)
default constructor
include the inlined functions if necessary
Definition CSVParser.h:54
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
unsigned int getNumberOfThreads()
returns the max number of threads used by default when entering the next parallel region
STL namespace.