aGrUM
0.21.0
a C++ library for (probabilistic) graphical models
MCBayesNetGenerator_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 Source implementation of MCBayesNetGenerator
24
*
25
* @author Pierre-Henri WUILLEMIN(@LIP6) and Ariele-Paolo MAESANO
26
*
27
*/
28
29
#
include
<
agrum
/
BN
/
generator
/
MCBayesNetGenerator
.
h
>
30
31
namespace
gum
{
32
33
#
ifdef
_MSC_VER
34
#
define
IBNG
IBayesNetGenerator
35
#
else
36
#
define
IBNG
IBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
>
37
#
endif
38
39
template
<
typename
GUM_SCALAR
>
40
gum
::
Size
getMaxModality
(
gum
::
BayesNet
<
GUM_SCALAR
>&
bayesNet
) {
41
gum
::
Size
maxMod
= 0;
42
43
for
(
auto
node
:
bayesNet
.
nodes
())
44
if
(
maxMod
<
bayesNet
.
variable
(
node
).
domainSize
())
45
maxMod
=
bayesNet
.
variable
(
node
).
domainSize
();
46
47
return
maxMod
;
48
}
49
50
// Default constructor.
51
// Use the SimpleCPTGenerator for generating the BNs CPT.
52
template
<
typename
GUM_SCALAR,
53
template
<
typename
>
54
class
ICPTGenerator,
55
template
<
typename
>
56
class
ICPTDisturber >
57
MCBayesNetGenerator< GUM_SCALAR, ICPTGenerator, ICPTDisturber >::MCBayesNetGenerator(
58
Size nbrNodes,
59
Size maxArcs,
60
Idx maxModality,
61
Size iteration,
62
Idx p,
63
Idx q) :
64
IBNG
(nbrNodes, maxArcs, maxModality),
65
bayesNettemp_(), hashMarginal_() {
66
if
(p + q > 100)
67
GUM_ERROR(OperationNotAllowed,
68
"the sum of the probabilities p and q must be at most equal to 100"
);
69
70
iteration_ = iteration;
71
p_ = p;
72
q_ = q;
73
disturbing_ =
false
;
74
75
GUM_CONSTRUCTOR(MCBayesNetGenerator);
76
}
77
78
template
<
typename
GUM_SCALAR
,
79
template
<
typename
>
80
class
ICPTGenerator
,
81
template
<
typename
>
82
class
ICPTDisturber
>
83
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
MCBayesNetGenerator
(
84
BayesNet
<
GUM_SCALAR
>
bayesNet
,
85
Size
iteration
,
86
Idx
p
,
87
Idx
q
) :
88
MCBayesNetGenerator
(
bayesNet
.
size
(),
89
(
Size
)(
bayesNet
.
sizeArcs
() * 1.1),
90
getMaxModality
(
bayesNet
)) {
91
iteration_
=
iteration
;
92
p_
=
p
;
93
q_
=
q
;
94
disturbing_
=
false
;
95
}
96
97
// Destructor.
98
template
<
typename
GUM_SCALAR
,
99
template
<
typename
>
100
class
ICPTGenerator
,
101
template
<
typename
>
102
class
ICPTDisturber
>
103
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::~
MCBayesNetGenerator
() {
104
GUM_DESTRUCTOR
(
MCBayesNetGenerator
);
105
}
106
107
template
<
typename
GUM_SCALAR
,
108
template
<
typename
>
109
class
ICPTGenerator
,
110
template
<
typename
>
111
class
ICPTDisturber
>
112
void
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
generateBN
(
113
BayesNet
<
GUM_SCALAR
>&
bayesNet
) {
114
Idx
iteration
=
iteration_
;
115
116
// this->bayesNet_ = bayesNet;
117
_createTree_
(
this
->
nbrNodes_
);
118
_transformPoly_
(
this
->
nbrNodes_
/ 2);
119
bayesNettemp_
=
this
->
bayesNet_
;
120
_PMMx_poly_
();
121
122
this
->
fillCPT
();
123
iteration_
=
iteration
;
124
125
bayesNet
=
this
->
bayesNet_
;
126
}
127
128
// density represent de
129
template
<
typename
GUM_SCALAR
,
130
template
<
typename
>
131
class
ICPTGenerator
,
132
template
<
typename
>
133
class
ICPTDisturber
>
134
void
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
disturbBN
(
135
BayesNet
<
GUM_SCALAR
>&
bayesNetinit
,
136
Size
iteration
) {
// insert option for the variation
137
disturbing_
=
true
;
138
Size
iter
=
iteration_
;
139
140
if
(
iteration
)
iteration_
=
iteration
;
141
142
this
->
bayesNet_
=
bayesNetinit
;
143
144
if
(
_checkConditions_
()) {
145
LazyPropagation
<
GUM_SCALAR
>
inf
(&
bayesNetinit
);
146
inf
.
makeInference
();
147
148
for
(
auto
node
:
bayesNetinit
.
nodes
()) {
149
auto
pottemp
=
new
Potential
<
GUM_SCALAR
>();
150
pottemp
->
copy
(
inf
.
posterior
(
node
));
151
hashMarginal_
.
insert
(
node
,
pottemp
);
152
}
153
154
bayesNettemp_
=
this
->
bayesNet_
;
155
156
if
(
_isPolytree_
())
157
_PMMx_poly_
();
158
else
159
_PMMx_multi_
();
160
161
bayesNetinit
= (
this
->
bayesNet_
);
162
163
while
(
hashMarginal_
.
size
()) {
164
delete
(
hashMarginal_
.
begin
().
val
());
165
hashMarginal_
.
erase
(
hashMarginal_
.
beginSafe
());
// safe iterator needed here.
166
}
167
168
}
else
{
169
std
::
cout
<<
this
->
bayesNet_
.
toDot
() <<
std
::
endl
;
170
GUM_ERROR
(
OperationNotAllowed
,
"BN is not valid cause it does not respect constraint "
)
171
}
172
173
iteration_
=
iter
;
174
disturbing_
=
false
;
175
}
176
177
template
<
typename
GUM_SCALAR
,
178
template
<
typename
>
179
class
ICPTGenerator
,
180
template
<
typename
>
181
class
ICPTDisturber
>
182
INLINE
bool
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_checkConditions_
() {
183
return
this
->
maxArcs_
>=
this
->
bayesNet_
.
sizeArcs
();
184
}
185
186
// main algorithme for moving between state of the IBayesNet according on the
187
// nature of the topology polytree or multi-connected
188
189
template
<
typename
GUM_SCALAR
,
190
template
<
typename
>
191
class
ICPTGenerator
,
192
template
<
typename
>
193
class
ICPTDisturber
>
194
void
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_PMMx_poly_
() {
195
if
(!
iteration_
--)
return
;
196
197
Idx
per
=
randomValue
(100);
198
199
if
(
per
<
p_
) {
200
_AorR_
();
201
202
if
(
_checkConditions_
()) {
203
bayesNettemp_
=
this
->
bayesNet_
;
204
_PMMx_multi_
();
205
}
else
{
206
this
->
bayesNet_
=
bayesNettemp_
;
207
_PMMx_poly_
();
208
}
209
}
else
{
210
if
(
per
<
p_
+
q_
) {
211
_AR_
();
212
213
if
(!
_checkConditions_
()) {
214
this
->
bayesNet_
=
bayesNettemp_
;
215
}
else
216
bayesNettemp_
=
this
->
bayesNet_
;
217
218
_PMMx_poly_
();
219
}
else
{
220
_jump_poly_
();
221
222
if
(
_checkConditions_
()) {
223
bayesNettemp_
=
this
->
bayesNet_
;
224
_PMMx_multi_
();
225
226
}
else
{
227
this
->
bayesNet_
=
bayesNettemp_
;
228
_PMMx_poly_
();
229
}
230
}
231
}
232
}
233
234
template
<
typename
GUM_SCALAR
,
235
template
<
typename
>
236
class
ICPTGenerator
,
237
template
<
typename
>
238
class
ICPTDisturber
>
239
void
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_PMMx_multi_
() {
240
if
(!
iteration_
--)
return
;
241
242
Idx
per
=
randomValue
(100);
243
244
if
(
per
<
p_
+
q_
) {
245
_AorR_
();
246
247
if
(
_checkConditions_
()) {
248
if
(
_isPolytree_
()) {
249
if
(
per
<
p_
) {
250
bayesNettemp_
=
this
->
bayesNet_
;
251
_PMMx_poly_
();
252
}
else
{
253
this
->
bayesNet_
=
bayesNettemp_
;
254
_PMMx_multi_
();
255
}
256
}
else
{
257
bayesNettemp_
=
this
->
bayesNet_
;
258
_PMMx_multi_
();
259
}
260
}
else
{
261
this
->
bayesNet_
=
bayesNettemp_
;
262
_PMMx_multi_
();
263
}
264
}
else
{
265
_jump_multi_
();
266
267
if
(
_checkConditions_
()) {
268
bayesNettemp_
=
this
->
bayesNet_
;
269
270
if
(
_isPolytree_
())
271
_PMMx_poly_
();
272
else
273
_PMMx_multi_
();
274
275
}
else
{
276
this
->
bayesNet_
=
bayesNettemp_
;
277
_PMMx_multi_
();
278
}
279
}
280
}
281
282
template
<
typename
GUM_SCALAR
,
283
template
<
typename
>
284
class
ICPTGenerator
,
285
template
<
typename
>
286
class
ICPTDisturber
>
287
void
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_AorR_
() {
288
NodeId
i
,
j
;
289
_chooseNodes_
(
i
,
j
);
290
const
DAG
_dag_
=
this
->
bayesNet_
.
dag
();
291
292
if
(
_dag_
.
existsArc
(
i
,
j
)) {
293
_eraseArc_
(
i
,
j
);
294
295
return
;
296
}
else
297
_insertArc_
(
i
,
j
);
298
}
299
300
template
<
typename
GUM_SCALAR
,
301
template
<
typename
>
302
class
ICPTGenerator
,
303
template
<
typename
>
304
class
ICPTDisturber
>
305
void
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_AR_
() {
306
NodeId
i
,
j
,
head
,
tail
;
307
_chooseNodes_
(
i
,
j
);
308
const
DAG
_dag_
=
this
->
bayesNet_
.
dag
();
309
310
if
(
_dag_
.
existsArc
(
i
,
j
) ||
_dag_
.
existsArc
(
j
,
i
)) {
311
return
;
312
}
else
{
313
Idx
per
=
randomValue
(100);
314
315
if
(
per
< 50) {
316
head
=
i
;
317
tail
=
j
;
318
}
else
{
319
head
=
j
;
320
tail
=
i
;
321
}
322
323
for
(
auto
node
:
_dag_
.
parents
(
j
)) {
324
NodeSet
excluded
;
325
excluded
.
insert
(
j
);
326
327
if
(
_connect_
(
node
,
i
,
excluded
)) {
328
this
->
bayesNet_
.
eraseArc
(
node
,
j
);
329
this
->
bayesNet_
.
addArc
(
head
,
tail
);
330
return
;
331
}
332
}
333
334
for
(
auto
node
:
_dag_
.
children
(
j
)) {
335
NodeSet
excluded
;
336
excluded
.
insert
(
j
);
337
338
if
(
_connect_
(
node
,
i
,
excluded
)) {
339
this
->
bayesNet_
.
eraseArc
(
j
,
node
);
340
this
->
bayesNet_
.
addArc
(
head
,
tail
);
341
return
;
342
}
343
}
344
}
345
}
346
347
template
<
typename
GUM_SCALAR
,
348
template
<
typename
>
349
class
ICPTGenerator
,
350
template
<
typename
>
351
class
ICPTDisturber
>
352
INLINE
void
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_jump_poly_
() {
353
NodeId
i
,
j
;
354
_chooseNodes_
(
i
,
j
);
355
const
DAG
_dag_
=
this
->
bayesNet_
.
dag
();
356
357
if
(!
_dag_
.
existsArc
(
i
,
j
))
_insertArc_
(
i
,
j
);
358
}
359
360
template
<
typename
GUM_SCALAR
,
361
template
<
typename
>
362
class
ICPTGenerator
,
363
template
<
typename
>
364
class
ICPTDisturber
>
365
void
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_jump_multi_
() {
366
NodeId
i
,
j
;
367
_chooseNodes_
(
i
,
j
);
368
const
DAG
_dag_
=
this
->
bayesNet_
.
dag
();
369
370
if
(
_dag_
.
existsArc
(
i
,
j
)) {
_eraseArc_
(
i
,
j
); }
371
}
372
373
template
<
typename
GUM_SCALAR
,
374
template
<
typename
>
375
class
ICPTGenerator
,
376
template
<
typename
>
377
class
ICPTDisturber
>
378
INLINE
void
379
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_insertArc_
(
NodeId
i
,
380
NodeId
j
) {
381
if
(
_directedPath_
(
j
,
i
))
return
;
382
383
if
(
disturbing_
) {
384
auto
potj
=
this
->
bayesNet_
.
cpt
(
j
);
385
this
->
bayesNet_
.
addArc
(
i
,
j
);
386
387
this
->
disturbAugmCPT
(
j
,
this
->
bayesNet_
,
potj
, (
GUM_SCALAR
)0.5);
388
}
else
389
this
->
bayesNet_
.
addArc
(
i
,
j
);
390
}
391
392
template
<
typename
GUM_SCALAR
,
393
template
<
typename
>
394
class
ICPTGenerator
,
395
template
<
typename
>
396
class
ICPTDisturber
>
397
INLINE
void
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_eraseArc_
(
398
NodeId
i
,
399
NodeId
j
,
400
bool
mustbeconnex
) {
401
if
(
disturbing_
) {
402
const
BayesNet
<
GUM_SCALAR
>
bayesNet
(
this
->
bayesNet_
);
403
Potential
<
GUM_SCALAR
>
potj
;
404
potj
.
copy
(
this
->
bayesNet_
.
cpt
(
j
));
405
this
->
bayesNet_
.
eraseArc
(
i
,
j
);
406
407
if
(
_connect_
(
i
,
j
) || !
mustbeconnex
) {
408
auto
marg
= *
hashMarginal_
[
i
];
409
410
this
->
disturbReducCPT
(
j
,
this
->
bayesNet_
,
potj
,
marg
);
411
}
else
412
this
->
bayesNet_
.
addArc
(
i
,
j
);
413
}
else
{
414
this
->
bayesNet_
.
eraseArc
(
i
,
j
);
415
416
if
(!
_connect_
(
i
,
j
) &&
mustbeconnex
) {
this
->
bayesNet_
.
addArc
(
i
,
j
); }
417
}
418
}
419
420
template
<
typename
GUM_SCALAR
,
421
template
<
typename
>
422
class
ICPTGenerator
,
423
template
<
typename
>
424
class
ICPTDisturber
>
425
INLINE
void
426
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_chooseNodes_
(
NodeId
&
i
,
427
NodeId
&
j
) {
428
i
=
randomValue
(
this
->
bayesNet_
.
size
());
429
j
=
randomValue
(
this
->
bayesNet_
.
size
());
430
431
while
(
i
==
j
)
432
j
=
randomValue
(
this
->
bayesNet_
.
size
());
433
}
434
435
template
<
typename
GUM_SCALAR
,
436
template
<
typename
>
437
class
ICPTGenerator
,
438
template
<
typename
>
439
class
ICPTDisturber
>
440
void
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_chooseCloseNodes_
(
441
NodeId
&
i
,
442
NodeId
&
j
) {
443
NodeId
temp
=
randomValue
(
this
->
bayesNet_
.
size
());
444
Size
co
= 0;
445
446
if
(
this
->
bayesNet_
.
parents
(
temp
).
size
()) {
447
j
=
temp
;
448
auto
it
=
this
->
bayesNet_
.
parents
(
j
).
begin
();
449
co
=
randomValue
(
this
->
bayesNet_
.
parents
(
j
).
size
());
450
451
while
(
co
--) {
452
++
it
;
453
}
454
455
i
= *
it
;
456
}
else
if
(
this
->
bayesNet_
.
children
(
temp
).
size
()) {
457
i
=
temp
;
458
auto
it
=
this
->
bayesNet_
.
children
(
i
).
begin
();
459
co
=
randomValue
(
this
->
bayesNet_
.
children
(
i
).
size
());
460
461
while
(
co
--) {
462
++
it
;
463
}
464
465
j
= *
it
;
466
}
else
{
467
GUM_ERROR
(
FatalError
,
"Sorry Misconstructed BN because of isolated node."
)
468
}
469
}
470
471
template
<
typename
GUM_SCALAR
,
472
template
<
typename
>
473
class
ICPTGenerator
,
474
template
<
typename
>
475
class
ICPTDisturber
>
476
void
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_createTree_
(
Size
BNSize
) {
477
Idx
n
= 0;
478
Size
nb_mod
= 2 +
randomValue
(
this
->
maxModality_
- 1);
479
std
::
stringstream
strBuff
;
480
strBuff
<<
"n_"
<<
n
++;
481
NodeId
root
=
this
->
bayesNet_
.
add
(
LabelizedVariable
(
strBuff
.
str
(),
""
,
nb_mod
));
482
Size
maxNodes
=
BNSize
- 1;
483
Size
SubG
= 0;
484
485
while
(
maxNodes
) {
486
SubG
=
randomValue
(
maxNodes
) + 1;
487
maxNodes
=
maxNodes
-
SubG
;
488
NodeId
rootS
=
_createPartTree_
(
SubG
,
n
);
489
this
->
bayesNet_
.
addArc
(
root
,
rootS
);
490
}
491
}
492
493
template
<
typename
GUM_SCALAR
,
494
template
<
typename
>
495
class
ICPTGenerator
,
496
template
<
typename
>
497
class
ICPTDisturber
>
498
NodeId
499
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_createPartTree_
(
Size
BNSize
,
500
Idx
&
n
) {
501
Size
nb_mod
= 2 +
randomValue
(
this
->
maxModality_
- 1);
502
std
::
stringstream
strBuff
;
503
strBuff
<<
"n_"
<<
n
++;
504
NodeId
root
=
this
->
bayesNet_
.
add
(
LabelizedVariable
(
strBuff
.
str
(),
""
,
nb_mod
));
505
Size
maxNodes
=
BNSize
- 1;
506
Size
SubG
= 0;
507
508
while
(
maxNodes
) {
509
SubG
=
randomValue
(
maxNodes
) + 1;
510
maxNodes
=
maxNodes
-
SubG
;
511
NodeId
rootS
=
_createPartTree_
(
SubG
,
n
);
512
this
->
bayesNet_
.
addArc
(
root
,
rootS
);
513
}
514
515
return
root
;
516
}
517
518
// Allow to invert maximum nbiter arc to use from polytree only
519
template
<
typename
GUM_SCALAR
,
520
template
<
typename
>
521
class
ICPTGenerator
,
522
template
<
typename
>
523
class
ICPTDisturber
>
524
void
525
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_transformPoly_
(
Idx
nbiter
) {
526
while
(
nbiter
--) {
527
NodeId
i
,
j
;
528
_chooseCloseNodes_
(
i
,
j
);
529
bayesNettemp_
=
this
->
bayesNet_
;
530
_eraseArc_
(
i
,
j
,
false
);
531
this
->
bayesNet_
.
addArc
(
j
,
i
);
532
533
if
(!
_checkConditions_
())
this
->
bayesNet_
=
bayesNettemp_
;
534
}
535
}
536
537
template
<
typename
GUM_SCALAR
,
538
template
<
typename
>
539
class
ICPTGenerator
,
540
template
<
typename
>
541
class
ICPTDisturber
>
542
INLINE
bool
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_isPolytree_
() {
543
const
DAG
_dag_
=
this
->
bayesNet_
.
dag
();
544
return
this
->
bayesNet_
.
size
() - 1 ==
this
->
bayesNet_
.
sizeArcs
();
545
}
546
547
template
<
typename
GUM_SCALAR
,
548
template
<
typename
>
549
class
ICPTGenerator
,
550
template
<
typename
>
551
class
ICPTDisturber
>
552
bool
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_connect_
(
const
NodeId
i
,
553
const
NodeId
j
) {
554
const
DAG
_dag_
=
this
->
bayesNet_
.
dag
();
555
556
if
(
_dag_
.
existsArc
(
i
,
j
) ||
_dag_
.
existsArc
(
j
,
i
))
557
return
true
;
558
else
{
559
NodeSet
excluded
;
560
excluded
.
insert
(
i
);
561
562
for
(
auto
par
:
_dag_
.
parents
(
i
)) {
563
if
(!
excluded
.
exists
(
par
) &&
_connect_
(
par
,
j
,
excluded
))
return
true
;
564
}
565
566
for
(
auto
chi
:
_dag_
.
children
(
i
)) {
567
if
(!
excluded
.
exists
(
chi
) &&
_connect_
(
chi
,
j
,
excluded
))
return
true
;
568
}
569
570
return
false
;
571
}
572
}
573
574
template
<
typename
GUM_SCALAR
,
575
template
<
typename
>
576
class
ICPTGenerator
,
577
template
<
typename
>
578
class
ICPTDisturber
>
579
bool
580
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_connect_
(
const
NodeId
i
,
581
const
NodeId
j
,
582
NodeSet
&
excluded
) {
583
const
DAG
_dag_
=
this
->
bayesNet_
.
dag
();
584
585
if
(
_dag_
.
existsArc
(
i
,
j
) ||
_dag_
.
existsArc
(
j
,
i
))
586
return
true
;
587
else
{
588
excluded
.
insert
(
i
);
589
590
for
(
auto
par
:
_dag_
.
parents
(
i
)) {
591
if
(!
excluded
.
exists
(
par
) &&
_connect_
(
par
,
j
,
excluded
))
return
true
;
592
}
593
594
for
(
auto
chi
:
_dag_
.
children
(
i
)) {
595
if
(!
excluded
.
exists
(
chi
) &&
_connect_
(
chi
,
j
,
excluded
))
return
true
;
596
}
597
598
return
false
;
599
}
600
}
601
602
template
<
typename
GUM_SCALAR
,
603
template
<
typename
>
604
class
ICPTGenerator
,
605
template
<
typename
>
606
class
ICPTDisturber
>
607
bool
608
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_directedPath_
(
NodeId
tail
,
609
NodeId
head
) {
610
const
DAG
_dag_
=
this
->
bayesNet_
.
dag
();
611
612
if
(
_dag_
.
existsArc
(
tail
,
head
))
613
return
true
;
614
else
{
615
NodeSet
excluded
;
616
excluded
.
insert
(
tail
);
617
618
for
(
auto
node
:
_dag_
.
children
(
tail
)) {
619
if
(
_directedPath_
(
node
,
head
,
excluded
))
return
true
;
620
}
621
622
return
false
;
623
}
624
}
625
626
template
<
typename
GUM_SCALAR
,
627
template
<
typename
>
628
class
ICPTGenerator
,
629
template
<
typename
>
630
class
ICPTDisturber
>
631
bool
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
_directedPath_
(
632
NodeId
tail
,
633
NodeId
head
,
634
NodeSet
&
excluded
) {
635
const
DAG
_dag_
=
this
->
bayesNet_
.
dag
();
636
637
if
(
_dag_
.
existsArc
(
tail
,
head
))
638
return
true
;
639
else
{
640
excluded
.
insert
(
tail
);
641
642
for
(
auto
node
:
_dag_
.
children
(
tail
)) {
643
if
(!
excluded
.
exists
(
node
) &&
_directedPath_
(
node
,
head
,
excluded
))
return
true
;
644
}
645
646
return
false
;
647
}
648
}
649
650
template
<
typename
GUM_SCALAR
,
651
template
<
typename
>
652
class
ICPTGenerator
,
653
template
<
typename
>
654
class
ICPTDisturber
>
655
INLINE
Size
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
iteration
()
const
{
656
return
iteration_
;
657
}
658
659
template
<
typename
GUM_SCALAR
,
660
template
<
typename
>
661
class
ICPTGenerator
,
662
template
<
typename
>
663
class
ICPTDisturber
>
664
INLINE
Idx
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
p
()
const
{
665
return
p_
;
666
}
667
668
template
<
typename
GUM_SCALAR
,
669
template
<
typename
>
670
class
ICPTGenerator
,
671
template
<
typename
>
672
class
ICPTDisturber
>
673
INLINE
Idx
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
q
()
const
{
674
return
q_
;
675
}
676
677
template
<
typename
GUM_SCALAR
,
678
template
<
typename
>
679
class
ICPTGenerator
,
680
template
<
typename
>
681
class
ICPTDisturber
>
682
INLINE
void
683
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
setIteration
(
Size
iteration
) {
684
iteration_
=
iteration
;
685
}
686
template
<
typename
GUM_SCALAR
,
687
template
<
typename
>
688
class
ICPTGenerator
,
689
template
<
typename
>
690
class
ICPTDisturber
>
691
INLINE
void
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
setP
(
Idx
p
) {
692
p_
=
p
;
693
694
if
(
p
+
q_
> 100)
695
GUM_ERROR
(
OperationNotAllowed
,
696
"the sum of the probabilities p and q must be at most equal to 100"
);
697
}
698
template
<
typename
GUM_SCALAR
,
699
template
<
typename
>
700
class
ICPTGenerator
,
701
template
<
typename
>
702
class
ICPTDisturber
>
703
INLINE
void
MCBayesNetGenerator
<
GUM_SCALAR
,
ICPTGenerator
,
ICPTDisturber
>::
setQ
(
Idx
q
) {
704
q_
=
q
;
705
706
if
(
p_
+
q
> 100)
707
GUM_ERROR
(
OperationNotAllowed
,
708
"the sum of the probabilities p and q must be at most equal to 100"
);
709
}
710
711
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643
gum::getMaxModality
gum::Size getMaxModality(gum::BayesNet< GUM_SCALAR > &bayesNet)
Definition:
MCBayesNetGenerator_tpl.h:40
IBNG
#define IBNG
Definition:
maxInducedWidthMCBayesNetGenerator_tpl.h:37