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 
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
61 
62  // if the marks of the node do not exist, create them
64 
65  // bounce the ball toward the neighbors
66  if (nodes_to_visit.front().second) { // visit from a child
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
87 
90 
91  if (is_evidence && !marks[node].first) {
92  marks[node].first = true;
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 */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643