aGrUM  0.17.2
a C++ library for (probabilistic) graphical models
MarkovBlanket.cpp
Go to the documentation of this file.
1 
31 
32 #ifdef GUM_NO_INLINE
34 #endif // GUM_NOINLINE
35 
36 namespace gum {
37  MarkovBlanket::MarkovBlanket(const DAGmodel& m, NodeId id, int level) :
38  __model(m), __node(id) {
39  if (level < 1)
40  GUM_ERROR(InvalidArgument, "Argument level(=" << level << ") must be >0.")
41 
42  NodeSet done;
44  done.insert(__node);
45 
46  while (level > 1) {
47  level--;
48  auto todo = __mb.nodes().asNodeSet() - done;
49  bool anythingnew = false;
50  for (NodeId n: todo) {
51  done.insert(n);
52  if (__buildMarkovBlanket(n)) anythingnew = true;
53  }
54  if (!anythingnew) break;
55  }
56 
57  // we add now some arcs that are between the nodes in __mb but are not part of
58  // the last ones.
59  // For instance, an arc between a parent and a parent of children
60  for (const auto node: __mb.nodes()) {
61  for (const auto child: __model.children(node)) {
62  if (__mb.existsNode(child) && !__mb.existsArc(Arc(node, child))) {
63  __mb.addArc(node, child);
64  __specialArcs.insert(Arc(node, child));
65  }
66  }
67  }
68  }
69 
71  const std::string& name,
72  int level) :
73  MarkovBlanket(m, m.idFromName(name), level) {}
74 
76 
78  bool change = false;
79  if (!__model.nodes().exists(node))
80  GUM_ERROR(InvalidArgument, "Node " << node << " does not exist.");
81 
82  if (!__mb.nodes().exists(node)) {
83  __mb.addNodeWithId(node);
84  change = true;
85  }
86 
87  for (const auto& parent: __model.parents(node)) {
88  if (!__mb.nodes().exists(parent)) {
89  __mb.addNodeWithId(parent);
90  change = true;
91  }
92  __mb.addArc(parent, node);
93  }
94 
95  for (const auto& child: __model.children(node)) {
96  if (!__mb.nodes().exists(child)) {
97  __mb.addNodeWithId(child);
98  change = true;
99  }
100  __mb.addArc(node, child);
101  for (const auto& opar: __model.parents(child)) {
102  if (opar != node) {
103  if (!__mb.nodes().exists(opar)) {
104  __mb.addNodeWithId(opar);
105  change = true;
106  }
107  __mb.addArc(opar, child);
108  }
109  }
110  }
111 
112  return change;
113  }
114 
116  if (size() != other.size()) return false;
117 
118  if (sizeArcs() != other.sizeArcs()) return false;
119 
120  for (const auto& nid: nodes()) {
121  try {
122  other.idFromName(__model.variable(nid).name());
123  } catch (NotFound) { return false; }
124  }
125 
126  for (const auto& arc: arcs()) {
127  if (!other.arcs().exists(
128  Arc(other.idFromName(__model.variable(arc.tail()).name()),
129  other.idFromName(__model.variable(arc.head()).name()))))
130  return false;
131  }
132 
133  return true;
134  }
135 
136  std::string MarkovBlanket::toDot() const {
137  std::stringstream output;
138  std::stringstream nodeStream;
139  std::stringstream arcStream;
140  List< NodeId > treatedNodes;
141  output << "digraph \""
142  << "no_name\" {" << std::endl;
143  nodeStream << "node [shape = ellipse];" << std::endl;
144  std::string tab = " ";
145 
146  for (const auto node: __mb.nodes()) {
147  nodeStream << tab << node << "[label=\"" << __model.variable(node).name()
148  << "\"";
149  if (node == __node) { nodeStream << ", color=red"; }
150  nodeStream << "];" << std::endl;
151 
152  for (const auto chi: __mb.children(node)) {
153  arcStream << tab << node << " -> " << chi;
154  if (__specialArcs.exists(Arc(node, chi))) { arcStream << " [color=grey]"; }
155  arcStream << ";" << std::endl;
156  }
157  }
158 
159  output << nodeStream.str() << std::endl
160  << arcStream.str() << std::endl
161  << "}" << std::endl;
162 
163  return output.str();
164  }
165 } // namespace gum
const ArcSet & arcs() const
returns the set of nodes with arc ingoing to a given node
Definition: DAGmodel_inl.h:44
virtual void addNodeWithId(const NodeId id)
try to insert a node with the given id
Virtual base class for PGMs using a DAG.
Definition: DAGmodel.h:47
const NodeSet & children(const NodeId id) const
returns the set of nodes with arc outgoing from a given node
Definition: DAGmodel_inl.h:53
Size sizeArcs() const
wrapping DAG::sizeArcs()
const NodeSet & parents(const NodeId id) const
returns the set of nodes with arc ingoing to a given node
Definition: DAGmodel_inl.h:46
Copyright 2005-2020 Pierre-Henri WUILLEMIN () et Christophe GONZALES () info_at_agrum_dot_org.
Size sizeArcs() const
Returns the number of arcs in this Directed Graphical Model.
Definition: DAGmodel_inl.h:42
virtual Size size() const final
Returns the number of variables in this Directed Graphical Model.
Definition: DAGmodel_inl.h:39
bool exists(const NodeId id) const
alias for existsNode
Generic doubly linked lists.
Definition: list.h:372
Copyright 2005-2020 Pierre-Henri WUILLEMIN () et Christophe GONZALES () info_at_agrum_dot_org.
Definition: agrum.h:25
const NodeId __node
Definition: MarkovBlanket.h:95
Class building the markov Blanket from a BN and a nodeName.
Definition: MarkovBlanket.h:49
bool __buildMarkovBlanket(const NodeId id)
std::string toDot() const
Size size() const
wrapping DAG::size()
virtual NodeId idFromName(const std::string &name) const =0
Getter by name.
bool hasSameStructure(const DAGmodel &other)
const ArcSet & arcs() const
wrapping DAG::arcs()
bool exists(const Key &k) const
Indicates whether a given elements belong to the set.
Definition: set_tpl.h:609
MarkovBlanket(const DAGmodel &m, NodeId n, int level=1)
The base class for all directed edgesThis class is used as a basis for manipulating all directed edge...
Copyright 2005-2020 Pierre-Henri WUILLEMIN () et Christophe GONZALES () info_at_agrum_dot_org.
const NodeGraphPart & nodes() const
Returns a constant reference to the dag of this Bayes Net.
Definition: DAGmodel_inl.h:60
const DAGmodel & __model
Definition: MarkovBlanket.h:93
NodeSet asNodeSet() const
returns a copy of the set of nodes represented by the NodeGraphPart
const NodeGraphPart & nodes() const
return *this as a NodeGraphPart
virtual const DiscreteVariable & variable(NodeId id) const =0
Returns a constant reference over a variable given it&#39;s node id.
virtual void addArc(const NodeId tail, const NodeId head)
insert a new arc into the directed graph
Definition: DAG_inl.h:43
bool existsNode(const NodeId id) const
returns true iff the NodeGraphPart contains the given nodeId
const NodeSet & children(const NodeId id) const
returns the set of nodes with arc outgoing from a given node
const std::string & name() const
returns the name of the variable
bool existsArc(const Arc &arc) const
indicates whether a given arc exists
Size NodeId
Type for node ids.
Definition: graphElements.h:98
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:615
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55
const NodeGraphPart & nodes() const
wrapping DAG::nodes()