aGrUM
0.20.2
a C++ library for (probabilistic) graphical models
graphChangesGenerator4K2_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 basic class for computing the next graph changes possible in a
24
* (directed) structure learning algorithm
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
GraphChangesGenerator4K2< STRUCT_CONSTRAINT >::GraphChangesGenerator4K2(
37
STRUCT_CONSTRAINT& constraint) :
38
constraint_(&constraint) {
39
GUM_CONSTRUCTOR(GraphChangesGenerator4K2);
40
}
41
42
/// copy constructor
43
template
<
typename
STRUCT_CONSTRAINT
>
44
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
GraphChangesGenerator4K2
(
45
const
GraphChangesGenerator4K2
&
from
) :
46
graph_
(
from
.
graph_
),
47
constraint_
(
from
.
constraint_
),
order_
(
from
.
order_
),
48
legal_changes_
(
from
.
legal_changes_
),
49
max_threads_number__
(
from
.
max_threads_number__
) {
50
GUM_CONS_CPY
(
GraphChangesGenerator4K2
);
51
}
52
53
/// move operator
54
template
<
typename
STRUCT_CONSTRAINT
>
55
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
GraphChangesGenerator4K2
(
56
GraphChangesGenerator4K2
&&
from
) :
57
graph_
(
std
::
move
(
from
.
graph_
)),
58
constraint_
(
from
.
constraint_
),
order_
(
std
::
move
(
from
.
order_
)),
59
legal_changes_
(
std
::
move
(
from
.
legal_changes_
)),
60
max_threads_number__
(
from
.
max_threads_number__
) {
61
GUM_CONS_MOV
(
GraphChangesGenerator4K2
);
62
}
63
64
/// destructor
65
template
<
typename
STRUCT_CONSTRAINT
>
66
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::~
GraphChangesGenerator4K2
() {
67
GUM_DESTRUCTOR
(
GraphChangesGenerator4K2
);
68
}
69
70
/// copy operator
71
template
<
typename
STRUCT_CONSTRAINT
>
72
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>&
73
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
operator
=(
74
const
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>&
from
) {
75
if
(
this
!= &
from
) {
76
graph_
=
from
.
graph_
;
77
constraint_
=
from
.
constraint_
;
78
order_
=
from
.
order_
;
79
legal_changes_
=
from
.
legal_changes_
;
80
max_threads_number__
=
from
.
max_threads_number__
;
81
}
82
return
*
this
;
83
}
84
85
/// move operator
86
template
<
typename
STRUCT_CONSTRAINT
>
87
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>&
88
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
operator
=(
89
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>&&
from
) {
90
if
(
this
!= &
from
) {
91
graph_
=
std
::
move
(
from
.
graph_
);
92
constraint_
=
std
::
move
(
from
.
constraint_
);
93
order_
=
std
::
move
(
from
.
order_
);
94
legal_changes_
=
std
::
move
(
from
.
legal_changes_
);
95
max_threads_number__
=
from
.
max_threads_number__
;
96
}
97
return
*
this
;
98
}
99
100
/// create the set of legal and illegal changes from a given graph
101
template
<
typename
STRUCT_CONSTRAINT
>
102
void
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
createChanges_
() {
103
legal_changes_
.
clear
();
104
105
// for all the pairs of nodes, consider adding, reverse and removing arcs
106
std
::
vector
<
Set
<
GraphChange
> >
legal_changes
;
107
#
pragma
omp
parallel
num_threads
(
int
(
max_threads_number__
)
)
108
{
109
int
num_threads
=
getNumberOfRunningThreads
();
110
111
#
pragma
omp
single
112
{
113
// resize the change vectors so that each thread can write to its
114
// own vector
115
legal_changes
.
resize
(
num_threads
);
116
}
117
118
const
Size
this_thread
=
getThreadNumber
();
119
120
for
(
Idx
i
= 0,
j
= 0;
j
<
order_
.
size
();
i
= (
i
+ 1) %
num_threads
, ++
j
) {
121
if
(
i
==
this_thread
) {
122
for
(
Idx
k
=
j
+ 1;
k
<
order_
.
size
(); ++
k
) {
123
// try arc additions
124
ArcAddition
arc_add
(
order_
[
j
],
order_
[
k
]);
125
if
(!
constraint_
->
isAlwaysInvalid
(
arc_add
)) {
126
legal_changes
[
this_thread
].
insert
(
std
::
move
(
arc_add
));
127
}
128
}
129
}
130
}
131
}
132
133
// now store the changes into the protected vectors of the
134
// GraphChangesGenerator4K2
135
for
(
const
auto
&
changes
:
legal_changes
) {
136
for
(
const
auto
&
change
:
changes
) {
137
legal_changes_
.
insert
(
std
::
move
(
change
));
138
}
139
}
140
}
141
142
/// sets a new graph from which the operator will compute possible changes
143
template
<
typename
STRUCT_CONSTRAINT
>
144
void
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
setGraph
(
145
const
DiGraph
&
graph
) {
146
// sets the current graph
147
graph_
=
graph
;
148
149
// check that all the nodes of the graph belong to the sequence.
150
// If some are missing, add them in increasing order into the sequence.
151
// If some element of order_ do not belong to the graph, remove them
152
for
(
auto
node
=
order_
.
beginSafe
();
node
!=
order_
.
endSafe
(); ++
node
) {
153
if
(!
graph
.
exists
(*
node
)) {
order_
.
erase
(
node
); }
154
}
155
for
(
const
auto
node
:
graph
) {
156
if
(!
order_
.
exists
(
node
)) {
order_
.
insert
(
node
); }
157
}
158
159
// generate the set of all changes
160
createChanges_
();
161
}
162
163
/// set a new order on the random variables
164
template
<
typename
STRUCT_CONSTRAINT
>
165
INLINE
void
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
setOrder
(
166
const
Sequence
<
NodeId
>&
order
) {
167
order_
=
order
;
168
}
169
170
/// set a new order on the random variables
171
template
<
typename
STRUCT_CONSTRAINT
>
172
INLINE
void
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
setOrder
(
173
const
std
::
vector
<
NodeId
>&
order
) {
174
order_
.
clear
();
175
for
(
const
auto
node
:
order
) {
176
order_
.
insert
(
node
);
177
}
178
}
179
180
/// empty the set of possible change operators that can be applied
181
template
<
typename
STRUCT_CONSTRAINT
>
182
INLINE
void
183
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
clearChanges
()
noexcept
{
184
legal_changes_
.
clear
();
185
}
186
187
/// returns an (unsafe) iterator on the beginning of the list of operators
188
template
<
typename
STRUCT_CONSTRAINT
>
189
INLINE
typename
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
iterator
190
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
begin
()
const
{
191
return
legal_changes_
.
cbegin
();
192
}
193
194
/// returns an (unsafe) iterator on the end of the list of operators
195
template
<
typename
STRUCT_CONSTRAINT
>
196
INLINE
const
typename
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
iterator
&
197
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
end
()
const
{
198
return
legal_changes_
.
cend
();
199
}
200
201
/// notify the operator set of a change applied to the graph
202
template
<
typename
STRUCT_CONSTRAINT
>
203
INLINE
void
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
modifyGraph
(
204
const
ArcAddition
&
change
) {}
205
206
/// notify the operator set of a change applied to the graph
207
template
<
typename
STRUCT_CONSTRAINT
>
208
INLINE
void
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
modifyGraph
(
209
const
ArcDeletion
&
change
) {}
210
211
/// notify the operator set of a change applied to the graph
212
template
<
typename
STRUCT_CONSTRAINT
>
213
INLINE
void
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
modifyGraph
(
214
const
ArcReversal
&
change
) {}
215
216
/// notify the operator set of a change applied to the graph
217
template
<
typename
STRUCT_CONSTRAINT
>
218
INLINE
void
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
modifyGraph
(
219
const
GraphChange
&
change
) {}
220
221
/// notifies the generator that we have parsed all its legal changes
222
template
<
typename
STRUCT_CONSTRAINT
>
223
INLINE
void
224
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
notifyGetCompleted
() {
225
if
(
legal_changes_
.
size
())
legal_changes_
.
clear
();
226
}
227
228
/// sets the maximum number of threads used to perform countings
229
template
<
typename
STRUCT_CONSTRAINT
>
230
INLINE
void
GraphChangesGenerator4K2
<
STRUCT_CONSTRAINT
>::
setMaxNbThreads
(
231
Size
nb
)
noexcept
{
232
#
if
defined
(
_OPENMP
)
&&
!
defined
(
GUM_DEBUG_MODE
)
233
if
(
nb
== 0)
nb
=
getMaxNumberOfThreads
();
234
max_threads_number__
=
nb
;
235
#
else
236
max_threads_number__
= 1;
237
#
endif
/* _OPENMP && GUM_DEBUG_MODE */
238
}
239
240
/// returns the constraint that is used by the generator
241
template
<
typename
STRUCT_CONSTRAINT
>
242
INLINE
STRUCT_CONSTRAINT
&
243
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 */
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