aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
graphChangesGeneratorOnSubDiGraph_tpl.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 class for computing the set of graph changes (over a subgraph)
24
* transmitted to learning algorithms
25
*
26
* @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
27
*/
28
#
ifndef
DOXYGEN_SHOULD_SKIP_THIS
29
30
namespace
gum
{
31
32
namespace
learning
{
33
34
/// default constructor
35
template
<
typename
STRUCT_CONSTRAINT >
36
GraphChangesGeneratorOnSubDiGraph< STRUCT_CONSTRAINT >::GraphChangesGeneratorOnSubDiGraph(
37
STRUCT_CONSTRAINT& constraint) :
38
constraint_(&constraint) {
39
GUM_CONSTRUCTOR(GraphChangesGeneratorOnSubDiGraph);
40
}
41
42
/// copy constructor
43
template
<
typename
STRUCT_CONSTRAINT
>
44
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
GraphChangesGeneratorOnSubDiGraph
(
45
const
GraphChangesGeneratorOnSubDiGraph
&
from
) :
46
constraint_
(
from
.
constraint_
),
47
target_nodes_
(
from
.
target_nodes_
),
tail_nodes_
(
from
.
tail_nodes_
),
48
legal_changes_
(
from
.
legal_changes_
),
_max_threads_number_
(
from
.
_max_threads_number_
) {
49
GUM_CONS_CPY
(
GraphChangesGeneratorOnSubDiGraph
);
50
}
51
52
/// move operator
53
template
<
typename
STRUCT_CONSTRAINT
>
54
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
GraphChangesGeneratorOnSubDiGraph
(
55
GraphChangesGeneratorOnSubDiGraph
&&
from
) :
56
constraint_
(
from
.
constraint_
),
57
target_nodes_
(
std
::
move
(
from
.
target_nodes_
)),
tail_nodes_
(
std
::
move
(
from
.
tail_nodes_
)),
58
legal_changes_
(
std
::
move
(
from
.
legal_changes_
)),
59
_max_threads_number_
(
from
.
_max_threads_number_
) {
60
GUM_CONS_MOV
(
GraphChangesGeneratorOnSubDiGraph
);
61
}
62
63
/// destructor
64
template
<
typename
STRUCT_CONSTRAINT
>
65
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::~
GraphChangesGeneratorOnSubDiGraph
() {
66
GUM_DESTRUCTOR
(
GraphChangesGeneratorOnSubDiGraph
);
67
}
68
69
/// copy operator
70
template
<
typename
STRUCT_CONSTRAINT
>
71
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>&
72
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
operator
=(
73
const
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>&
from
) {
74
if
(
this
!= &
from
) {
75
constraint_
=
from
.
constraint_
;
76
target_nodes_
=
from
.
target_nodes_
;
77
tail_nodes_
=
from
.
tail_nodes_
;
78
legal_changes_
=
from
.
legal_changes_
;
79
_max_threads_number_
=
from
.
_max_threads_number_
;
80
}
81
return
*
this
;
82
}
83
84
/// move operator
85
template
<
typename
STRUCT_CONSTRAINT
>
86
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>&
87
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
operator
=(
88
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>&&
from
) {
89
if
(
this
!= &
from
) {
90
constraint_
=
std
::
move
(
from
.
constraint_
);
91
target_nodes_
=
std
::
move
(
from
.
target_nodes_
);
92
tail_nodes_
=
std
::
move
(
from
.
tail_nodes_
);
93
legal_changes_
=
std
::
move
(
from
.
legal_changes_
);
94
_max_threads_number_
=
from
.
_max_threads_number_
;
95
}
96
return
*
this
;
97
}
98
99
/// create the set of legal and illegal changes from a given graph
100
template
<
typename
STRUCT_CONSTRAINT
>
101
void
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
createChanges_
() {
102
legal_changes_
.
clear
();
103
104
// for all the pairs of nodes, consider adding, reverse and removing arcs
105
std
::
vector
<
Set
<
GraphChange
> >
legal_changes
;
106
#
pragma
omp
parallel
num_threads
(
_max_threads_number_
)
107
{
108
int
num_threads
=
getNumberOfRunningThreads
();
109
110
#
pragma
omp
single
111
{
112
// resize the change vectors so that each thread can write to its
113
// own vector
114
legal_changes
.
resize
(
num_threads
);
115
}
116
117
const
Size
this_thread
=
getThreadNumber
();
118
119
Idx
i
= 0;
120
for
(
const
auto
node1
:
tail_nodes_
) {
121
if
(
i
==
this_thread
) {
122
for
(
const
auto
node2
:
target_nodes_
) {
123
if
(
node1
!=
node2
) {
124
// try arc additions
125
ArcAddition
arc_add
(
node1
,
node2
);
126
if
(!
constraint_
->
isAlwaysInvalid
(
arc_add
)) {
127
legal_changes
[
this_thread
].
insert
(
std
::
move
(
arc_add
));
128
}
129
130
// try arc deletion
131
ArcDeletion
arc_del
(
node1
,
node2
);
132
if
(!
constraint_
->
isAlwaysInvalid
(
arc_del
)) {
133
legal_changes
[
this_thread
].
insert
(
std
::
move
(
arc_del
));
134
}
135
136
// try arc reversal
137
ArcReversal
arc_rev
(
node1
,
node2
);
138
if
(!
constraint_
->
isAlwaysInvalid
(
arc_rev
)) {
139
legal_changes
[
this_thread
].
insert
(
std
::
move
(
arc_rev
));
140
}
141
}
142
}
143
}
144
++
i
;
145
i
%=
num_threads
;
146
}
147
}
148
149
// now store the changes into the protected vectors of the
150
// GraphChangesGeneratorOnSubDiGraph
151
for
(
const
auto
&
changes
:
legal_changes
) {
152
for
(
const
auto
&
change
:
changes
) {
153
legal_changes_
.
insert
(
std
::
move
(
change
));
154
}
155
}
156
}
157
158
/// sets a new graph from which the operator will compute possible changes
159
template
<
typename
STRUCT_CONSTRAINT
>
160
INLINE
void
161
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
setGraph
(
const
DiGraph
&
graph
) {
162
// generate the set of all changes
163
createChanges_
();
164
}
165
166
/// assign a set of target nodes
167
template
<
typename
STRUCT_CONSTRAINT
>
168
INLINE
void
169
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
setTargets
(
const
NodeSet
&
nodes
) {
170
target_nodes_
=
nodes
;
171
}
172
173
/// adds a new target node
174
template
<
typename
STRUCT_CONSTRAINT
>
175
INLINE
void
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
addTarget
(
NodeId
node
) {
176
target_nodes_
.
insert
(
node
);
177
}
178
179
/// removes a target
180
template
<
typename
STRUCT_CONSTRAINT
>
181
INLINE
void
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
eraseTarget
(
NodeId
node
) {
182
target_nodes_
.
erase
(
node
);
183
}
184
185
/// assign a set of "tail" nodes
186
template
<
typename
STRUCT_CONSTRAINT
>
187
INLINE
void
188
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
setTails
(
const
NodeSet
&
nodes
) {
189
tail_nodes_
=
nodes
;
190
}
191
192
/// assign a set of "tail" nodes
193
template
<
typename
STRUCT_CONSTRAINT
>
194
INLINE
void
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
setTails
(
Size
nb_nodes
) {
195
tail_nodes_
.
clear
();
196
for
(
Idx
i
= 0;
i
<
nb_nodes
; ++
i
) {
197
tail_nodes_
.
insert
(
i
);
198
}
199
}
200
201
/// adds a new "tail" node
202
template
<
typename
STRUCT_CONSTRAINT
>
203
INLINE
void
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
addTail
(
NodeId
node
) {
204
tail_nodes_
.
insert
(
node
);
205
}
206
207
/// removes a tail node
208
template
<
typename
STRUCT_CONSTRAINT
>
209
INLINE
void
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
eraseTail
(
NodeId
node
) {
210
tail_nodes_
.
erase
(
node
);
211
}
212
213
/// empty the set of possible change operators that can be applied
214
template
<
typename
STRUCT_CONSTRAINT
>
215
INLINE
void
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
clearChanges
()
noexcept
{
216
legal_changes_
.
clear
();
217
}
218
219
/// returns an (unsafe) iterator on the beginning of the list of operators
220
template
<
typename
STRUCT_CONSTRAINT
>
221
INLINE
typename
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
iterator
222
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
begin
()
const
{
223
return
legal_changes_
.
cbegin
();
224
}
225
226
/// returns an (unsafe) iterator on the end of the list of operators
227
template
<
typename
STRUCT_CONSTRAINT
>
228
INLINE
const
typename
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
iterator
&
229
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
end
()
const
{
230
return
legal_changes_
.
cend
();
231
}
232
233
/// notify the operator set of a change applied to the graph
234
template
<
typename
STRUCT_CONSTRAINT
>
235
INLINE
void
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
modifyGraph
(
236
const
ArcAddition
&
change
) {}
237
238
/// notify the operator set of a change applied to the graph
239
template
<
typename
STRUCT_CONSTRAINT
>
240
INLINE
void
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
modifyGraph
(
241
const
ArcDeletion
&
change
) {}
242
243
/// notify the operator set of a change applied to the graph
244
template
<
typename
STRUCT_CONSTRAINT
>
245
INLINE
void
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
modifyGraph
(
246
const
ArcReversal
&
change
) {}
247
248
/// notify the operator set of a change applied to the graph
249
template
<
typename
STRUCT_CONSTRAINT
>
250
INLINE
void
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
modifyGraph
(
251
const
GraphChange
&
change
) {}
252
253
/// notifies the generator that we have parsed all its legal changes
254
template
<
typename
STRUCT_CONSTRAINT
>
255
INLINE
void
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
notifyGetCompleted
() {
256
if
(
legal_changes_
.
size
())
legal_changes_
.
clear
();
257
}
258
259
/// sets the maximum number of threads used to perform countings
260
template
<
typename
STRUCT_CONSTRAINT
>
261
INLINE
void
262
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
setMaxNbThreads
(
Size
nb
)
noexcept
{
263
#
if
defined
(
_OPENMP
)
&&
!
defined
(
GUM_DEBUG_MODE
)
264
if
(
nb
== 0)
nb
=
getMaxNumberOfThreads
();
265
_max_threads_number_
=
nb
;
266
#
else
267
_max_threads_number_
= 1;
268
#
endif
/* _OPENMP && GUM_DEBUG_MODE */
269
}
270
271
/// returns the constraint that is used by the generator
272
template
<
typename
STRUCT_CONSTRAINT
>
273
INLINE
STRUCT_CONSTRAINT
&
274
GraphChangesGeneratorOnSubDiGraph
<
STRUCT_CONSTRAINT
>::
constraint
()
const
noexcept
{
275
return
*
constraint_
;
276
}
277
278
}
/* namespace learning */
279
280
}
/* namespace gum */
281
282
#
endif
/* DOXYGEN_SHOULD_SKIP_THIS */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643
gum::learning::genericBNLearner::Database::Database
Database(const std::string &filename, const BayesNet< GUM_SCALAR > &bn, const std::vector< std::string > &missing_symbols)
Definition:
genericBNLearner_tpl.h:31