aGrUM 3.1.1
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-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 template < typename STRUCT_CONSTRAINT >
60 STRUCT_CONSTRAINT& constraint) : constraint_(&constraint) {
61 GUM_CONSTRUCTOR(GraphChangesGenerator4K2);
62 }
63
65 template < typename STRUCT_CONSTRAINT >
66 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::GraphChangesGenerator4K2(
67 const GraphChangesGenerator4K2& from) :
68 graph_(from.graph_), constraint_(from.constraint_), order_(from.order_),
69 legal_changes_(from.legal_changes_), _max_threads_number_(from._max_threads_number_) {
70 GUM_CONS_CPY(GraphChangesGenerator4K2);
71 }
72
74 template < typename STRUCT_CONSTRAINT >
75 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::GraphChangesGenerator4K2(
76 GraphChangesGenerator4K2&& from) :
77 graph_(std::move(from.graph_)), constraint_(from.constraint_),
78 order_(std::move(from.order_)), legal_changes_(std::move(from.legal_changes_)),
79 _max_threads_number_(from._max_threads_number_) {
80 GUM_CONS_MOV(GraphChangesGenerator4K2);
81 }
82
84 template < typename STRUCT_CONSTRAINT >
85 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::~GraphChangesGenerator4K2() {
86 GUM_DESTRUCTOR(GraphChangesGenerator4K2);
87 }
88
90 template < typename STRUCT_CONSTRAINT >
91 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >&
92 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::operator=(
93 const GraphChangesGenerator4K2< STRUCT_CONSTRAINT >& from) {
94 if (this != &from) {
95 graph_ = from.graph_;
96 constraint_ = from.constraint_;
97 order_ = from.order_;
98 legal_changes_ = from.legal_changes_;
99 _max_threads_number_ = from._max_threads_number_;
100 }
101 return *this;
102 }
103
105 template < typename STRUCT_CONSTRAINT >
106 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >&
107 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::operator=(
108 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >&& from) {
109 if (this != &from) {
110 graph_ = std::move(from.graph_);
111 constraint_ = std::move(from.constraint_);
112 order_ = std::move(from.order_);
113 legal_changes_ = std::move(from.legal_changes_);
114 _max_threads_number_ = from._max_threads_number_;
115 }
116 return *this;
117 }
118
120 template < typename STRUCT_CONSTRAINT >
121 void GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::createChanges_() {
122 legal_changes_.clear();
123
124 // for all the pairs of nodes, consider adding, reverse and removing arcs
125 const Size nb_threads = _max_threads_number_;
126 std::vector< Set< GraphChange > > legal_changes(nb_threads);
127
128 // create the lambda that will be used to fill the legal changes
129 auto threadedLegalSet = [this, &legal_changes](const std::size_t this_thread,
130 const std::size_t nb_threads) -> void {
131 for (Idx i = 0, j = 0; j < this->order_.size(); i = (i + 1) % nb_threads, ++j) {
132 if (i == this_thread) {
133 for (Idx k = j + 1; k < this->order_.size(); ++k) {
134 // try arc additions
135 ArcAddition arc_add(order_[j], order_[k]);
136 if (!this->constraint_->isAlwaysInvalid(arc_add)) {
137 legal_changes[this_thread].insert(std::move(arc_add));
138 }
139 }
140 }
141 }
142 };
143
144 // launch the threads
145 ThreadExecutor::execute(nb_threads, threadedLegalSet);
146
147 // now store the changes into the protected vectors of the
148 // GraphChangesGenerator4K2
149 for (const auto& changes: legal_changes) {
150 for (const auto& change: changes) {
151 legal_changes_.insert(std::move(change));
152 }
153 }
154 }
155
157 template < typename STRUCT_CONSTRAINT >
158 void GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::setGraph(const DiGraph& graph) {
159 // sets the current graph
160 graph_ = graph;
161
162 // check that all the nodes of the graph belong to the sequence.
163 // If some are missing, add them in increasing order into the sequence.
164 // If some element of order_ do not belong to the graph, remove them
165 for (auto node = order_.beginSafe(); node != order_.endSafe(); ++node) {
166 if (!graph.exists(*node)) { order_.erase(node); }
167 }
168 for (const auto node: graph) {
169 if (!order_.exists(node)) { order_.insert(node); }
170 }
171
172 // generate the set of all changes
173 createChanges_();
174 }
175
177 template < typename STRUCT_CONSTRAINT >
178 void GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::setOrder(const Sequence< NodeId >& order) {
179 order_ = order;
180 }
181
183 template < typename STRUCT_CONSTRAINT >
184 void GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::setOrder(
185 const std::vector< NodeId >& order) {
186 order_.clear();
187 for (const auto node: order) {
188 order_.insert(node);
189 }
190 }
191
193 template < typename STRUCT_CONSTRAINT >
194 void GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::clearChanges() noexcept {
195 legal_changes_.clear();
196 }
197
199 template < typename STRUCT_CONSTRAINT >
200 typename GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::iterator
201 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::begin() const {
202 return legal_changes_.cbegin();
203 }
204
206 template < typename STRUCT_CONSTRAINT >
207 const typename GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::iterator&
208 GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::end() const {
209 return legal_changes_.cend();
210 }
211
213 template < typename STRUCT_CONSTRAINT >
214 void GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::modifyGraph(const ArcAddition& change) {}
215
217 template < typename STRUCT_CONSTRAINT >
218 void GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::modifyGraph(const ArcDeletion& change) {}
219
221 template < typename STRUCT_CONSTRAINT >
222 void GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::modifyGraph(const ArcReversal& change) {}
223
225 template < typename STRUCT_CONSTRAINT >
226 void GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::modifyGraph(const GraphChange& change) {}
227
229 template < typename STRUCT_CONSTRAINT >
230 void GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::notifyGetCompleted() {
231 if (legal_changes_.size()) legal_changes_.clear();
232 }
233
235 template < typename STRUCT_CONSTRAINT >
236 void GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::setMaxNbThreads(Size nb) noexcept {
237 if (nb == 0) nb = gum::getNumberOfThreads();
238 _max_threads_number_ = nb;
239 }
240
242 template < typename STRUCT_CONSTRAINT >
243 STRUCT_CONSTRAINT& GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::constraint() const noexcept {
244 return *constraint_;
245 }
246
247 } /* namespace learning */
248
249} /* namespace gum */
250
251#endif /* DOXYGEN_SHOULD_SKIP_THIS */
GraphChangesGenerator4K2(STRUCT_CONSTRAINT &constraint)
default constructor
The basic class for computing the set of digraph changes allowed by the user to be executed by the le...
include the inlined functions if necessary
Definition CSVParser.h:55
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.