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