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