aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
BayesBall.cpp
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
/**
23
* @file
24
* @brief Implementation of the BayesBall class.
25
*/
26
27
#
include
<
agrum
/
BN
/
algorithms
/
BayesBall
.
h
>
28
29
#
ifdef
GUM_NO_INLINE
30
#
include
<
agrum
/
BN
/
algorithms
/
BayesBall_inl
.
h
>
31
#
endif
// GUM_NO_INLINE
32
33
namespace
gum
{
34
35
void
BayesBall
::
requisiteNodes
(
const
DAG
&
dag
,
36
const
NodeSet
&
query
,
37
const
NodeSet
&
hardEvidence
,
38
const
NodeSet
&
softEvidence
,
39
NodeSet
&
requisite
) {
40
// for the moment, no node is requisite
41
requisite
.
clear
();
42
43
// create the marks (top = first and bottom = second )
44
NodeProperty
<
std
::
pair
<
bool
,
bool
> >
marks
(
dag
.
size
());
45
const
std
::
pair
<
bool
,
bool
>
empty_mark
(
false
,
false
);
46
47
// indicate that we will send the ball to all the query nodes (as children):
48
// in list nodes_to_visit, the first element is the next node to send the
49
// ball to and the Boolean indicates whether we shall reach it from one of
50
// its children (true) or from one parent (false)
51
List
<
std
::
pair
<
NodeId
,
bool
> >
nodes_to_visit
;
52
for
(
const
auto
node
:
query
) {
53
nodes_to_visit
.
insert
(
std
::
pair
<
NodeId
,
bool
>(
node
,
true
));
54
}
55
56
// perform the bouncing ball until there is no node in the graph to send
57
// the ball to
58
while
(!
nodes_to_visit
.
empty
()) {
59
// get the next node to visit
60
NodeId
node
=
nodes_to_visit
.
front
().
first
;
61
62
// if the marks of the node do not exist, create them
63
if
(!
marks
.
exists
(
node
))
marks
.
insert
(
node
,
empty_mark
);
64
65
// bounce the ball toward the neighbors
66
if
(
nodes_to_visit
.
front
().
second
) {
// visit from a child
67
nodes_to_visit
.
popFront
();
68
requisite
.
insert
(
node
);
69
70
if
(
hardEvidence
.
exists
(
node
)) {
continue
; }
71
72
if
(!
marks
[
node
].
first
) {
73
marks
[
node
].
first
=
true
;
// top marked
74
for
(
const
auto
par
:
dag
.
parents
(
node
)) {
75
nodes_to_visit
.
insert
(
std
::
pair
<
NodeId
,
bool
>(
par
,
true
));
76
}
77
}
78
79
if
(!
marks
[
node
].
second
) {
80
marks
[
node
].
second
=
true
;
// bottom marked
81
for
(
const
auto
chi
:
dag
.
children
(
node
)) {
82
nodes_to_visit
.
insert
(
std
::
pair
<
NodeId
,
bool
>(
chi
,
false
));
83
}
84
}
85
}
else
{
// visit from a parent
86
nodes_to_visit
.
popFront
();
87
88
const
bool
is_hard_evidence
=
hardEvidence
.
exists
(
node
);
89
const
bool
is_evidence
=
is_hard_evidence
||
softEvidence
.
exists
(
node
);
90
91
if
(
is_evidence
&& !
marks
[
node
].
first
) {
92
marks
[
node
].
first
=
true
;
93
requisite
.
insert
(
node
);
94
95
for
(
const
auto
par
:
dag
.
parents
(
node
)) {
96
nodes_to_visit
.
insert
(
std
::
pair
<
NodeId
,
bool
>(
par
,
true
));
97
}
98
}
99
100
if
(!
is_hard_evidence
&& !
marks
[
node
].
second
) {
101
marks
[
node
].
second
=
true
;
102
103
for
(
const
auto
chi
:
dag
.
children
(
node
)) {
104
nodes_to_visit
.
insert
(
std
::
pair
<
NodeId
,
bool
>(
chi
,
false
));
105
}
106
}
107
}
108
}
109
}
110
111
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643