aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
gum::EssentialGraph Class Reference

Class building the essential graph from a BN. More...

#include <agrum/BN/algorithms/essentialGraph.h>

Collaboration diagram for gum::EssentialGraph:

Public Member Functions

 EssentialGraph ()=default
 EssentialGraph (const DAGmodel &m)
 EssentialGraph (const DAGmodel &m, const PDAG &mg)
 EssentialGraph (const EssentialGraph &g)
EssentialGraphoperator= (const EssentialGraph &g)
 ~EssentialGraph ()
PDAG pdag () const
std::string toDot () const
const NodeSetparents (NodeId id) const
 wrapping MixedGraph::parents(id)
const NodeSetchildren (NodeId id) const
 wrapping MixedGraph::parents(id)
NodeSet parents (const NodeSet &ids) const
 wrapping MixedGraph::parents(ids)
NodeSet children (const NodeSet &ids) const
 wrapping MixedGraph::parents(ids)
const NodeSetneighbours (NodeId id) const
 wrapping MixedGraph::parents(id)
Size sizeArcs () const
 wrapping MixedGraph::sizeArcs()
const ArcSetarcs () const
 wrapping MixedGraph::arcs()
Size sizeEdges () const
 wrapping MixedGraph::sizeEdges()
const EdgeSetedges () const
 wrapping MixedGraph::edges()
Size sizeNodes () const
 wrapping MixedGraph::sizeNodes()
Size size () const
 wrapping MixedGraph::size()
UndiGraph skeleton () const
const NodeGraphPartnodes () const
 wrapping MixedGraph::nodes()
NodeId idFromName (const std::string &name) const
 wrappping DAGModel::idFromName()
const std::string & nameFromId (NodeId node) const
 wrappping .name()

Private Member Functions

void _buildEssentialGraph_ ()
bool _strongly_protected_ (NodeId a, NodeId b) const

Static Private Member Functions

static bool _strongly_protected_ (MixedGraph mg, NodeId a, NodeId b)

Private Attributes

const DAGmodel_dagmodel_
PDAG _pdag_

Detailed Description

Class building the essential graph from a BN.

Essential graph is a mixed graph (Chain Graph) that represents the class of markov equivalent Bayesian networks (with the same independence model).

The main goal of this class is to nest the algorithm to build the essential graph from a BN and to encapsulate the representation (as a MixedGraph) of the essential graph.

gum::operator<<(std::ostream&, const BayesNet<GUM_SCALAR>&).

Definition at line 74 of file essentialGraph.h.

Constructor & Destructor Documentation

◆ EssentialGraph() [1/4]

gum::EssentialGraph::EssentialGraph ( )
default

References EssentialGraph().

Referenced by EssentialGraph(), EssentialGraph(), and operator=().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ EssentialGraph() [2/4]

gum::EssentialGraph::EssentialGraph ( const DAGmodel & m)
explicit

Definition at line 56 of file essentialGraph.cpp.

const DAGmodel * _dagmodel_

References _buildEssentialGraph_(), and _dagmodel_.

Here is the call graph for this function:

◆ EssentialGraph() [3/4]

gum::EssentialGraph::EssentialGraph ( const DAGmodel & m,
const PDAG & mg )

Definition at line 58 of file essentialGraph.cpp.

58: _dagmodel_(&m), _pdag_(mg) {}

References _dagmodel_, and _pdag_.

◆ EssentialGraph() [4/4]

gum::EssentialGraph::EssentialGraph ( const EssentialGraph & g)

Definition at line 60 of file essentialGraph.cpp.

60 {
61 _dagmodel_ = g._dagmodel_;
63 }

References EssentialGraph(), _buildEssentialGraph_(), and _dagmodel_.

Here is the call graph for this function:

◆ ~EssentialGraph()

gum::EssentialGraph::~EssentialGraph ( )
default

Member Function Documentation

◆ _buildEssentialGraph_()

void gum::EssentialGraph::_buildEssentialGraph_ ( )
private

Definition at line 75 of file essentialGraph.cpp.

75 {
76 MixedGraph mg; // during the process, the graph may not be a PDAG
77 _pdag_.clear();
78 if (_dagmodel_ == nullptr) return;
79
80 for (const auto& node: _dagmodel_->nodes()) {
81 mg.addNodeWithId(node);
82 _pdag_.addNodeWithId(node);
83 }
84 for (const auto& arc: _dagmodel_->arcs()) {
85 mg.addArc(arc.tail(), arc.head());
86 }
87
88 std::vector< Arc > v;
89 do {
90 v.clear();
91 for (const auto x: _dagmodel_->topologicalOrder())
92 for (const auto y: mg.children(x))
93 if (!_strongly_protected_(mg, x, y)) v.emplace_back(x, y);
94
95 for (const auto& arc: v) {
96 mg.eraseArc(arc);
97 mg.addEdge(arc.tail(), arc.head());
98 }
99 } while (!v.empty());
100
101 for (const auto& arc: mg.arcs()) {
102 _pdag_.addArc(arc.tail(), arc.head());
103 }
104 for (const auto& edge: mg.edges()) {
105 _pdag_.addEdge(edge.first(), edge.second());
106 }
107 }
bool _strongly_protected_(NodeId a, NodeId b) const

References _dagmodel_, _pdag_, _strongly_protected_(), gum::DiGraph::addArc(), gum::UndiGraph::addEdge(), gum::NodeGraphPart::addNodeWithId(), gum::ArcGraphPart::arcs(), gum::ArcGraphPart::children(), gum::EdgeGraphPart::edges(), and gum::ArcGraphPart::eraseArc().

Referenced by EssentialGraph(), EssentialGraph(), and operator=().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _strongly_protected_() [1/2]

bool gum::EssentialGraph::_strongly_protected_ ( MixedGraph mg,
NodeId a,
NodeId b )
staticprivate

Definition at line 113 of file essentialGraph.cpp.

113 {
114 // testing a->b from
115 // A Characterization of Markov Equivalence Classes for Acyclic Digraphs (2001)
116 // Steen A. Andersson, David Madigan, and Michael D. Perlman*
117
118 // condition (a)
119 for (const auto& c: mg.parents(a)) {
120 if (!mg.existsArc(c, b)) { return true; }
121 }
122
123
124 for (const auto& c: mg.parents(b)) {
125 if (c == a) { continue; }
126 // condition (c)
127 if (mg.existsArc(a, c)) { return true; }
128
129 // condition (b) knowing that a can not be a parent of c (condition below)
130 if (!mg.existsEdge(a, c) && !mg.existsArc(c, a)) { return true; }
131 }
132
133 // condition (d)
134 bool oneFound = false;
135 for (const auto& c: mg.parents(b)) {
136 if (c == a) { continue; }
137 // condition (d)
138 if (mg.existsEdge(c, a)) {
139 if (oneFound) { // this is the second found
140 return true;
141 }
142 oneFound = true;
143 }
144 }
145
146 return false;
147 }

References gum::ArcGraphPart::existsArc(), gum::EdgeGraphPart::existsEdge(), and gum::ArcGraphPart::parents().

Here is the call graph for this function:

◆ _strongly_protected_() [2/2]

bool gum::EssentialGraph::_strongly_protected_ ( NodeId a,
NodeId b ) const
private

Definition at line 109 of file essentialGraph.cpp.

109 {
110 return _strongly_protected_(_pdag_, a, b);
111 }

References _pdag_, and _strongly_protected_().

Referenced by _buildEssentialGraph_(), and _strongly_protected_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ arcs()

INLINE const ArcSet & gum::EssentialGraph::arcs ( ) const

wrapping MixedGraph::arcs()

Definition at line 71 of file essentialGraph_inl.h.

71{ return _pdag_.arcs(); }

References _pdag_.

Referenced by skeleton().

Here is the caller graph for this function:

◆ children() [1/2]

INLINE NodeSet gum::EssentialGraph::children ( const NodeSet & ids) const

wrapping MixedGraph::parents(ids)

Definition at line 63 of file essentialGraph_inl.h.

63{ return _pdag_.children(ids); }

References _pdag_.

◆ children() [2/2]

INLINE const NodeSet & gum::EssentialGraph::children ( NodeId id) const

wrapping MixedGraph::parents(id)

Definition at line 59 of file essentialGraph_inl.h.

59{ return _pdag_.children(id); }

References _pdag_.

◆ edges()

INLINE const EdgeSet & gum::EssentialGraph::edges ( ) const

wrapping MixedGraph::edges()

Definition at line 75 of file essentialGraph_inl.h.

75{ return _pdag_.edges(); }

References _pdag_.

Referenced by skeleton().

Here is the caller graph for this function:

◆ idFromName()

INLINE NodeId gum::EssentialGraph::idFromName ( const std::string & name) const

wrappping DAGModel::idFromName()

Definition at line 83 of file essentialGraph_inl.h.

83 {
84 return _dagmodel_->idFromName(name);
85 };

References _dagmodel_.

◆ nameFromId()

INLINE const std::string & gum::EssentialGraph::nameFromId ( NodeId node) const

wrappping .name()

Definition at line 87 of file essentialGraph_inl.h.

87 {
88 return _dagmodel_->variable(node).name();
89 };

References _dagmodel_.

◆ neighbours()

INLINE const NodeSet & gum::EssentialGraph::neighbours ( NodeId id) const

wrapping MixedGraph::parents(id)

Definition at line 65 of file essentialGraph_inl.h.

65 {
66 return _pdag_.neighbours(id);
67 }

References _pdag_.

◆ nodes()

INLINE const NodeGraphPart & gum::EssentialGraph::nodes ( ) const

wrapping MixedGraph::nodes()

Definition at line 81 of file essentialGraph_inl.h.

81{ return _pdag_.nodes(); }

References _pdag_.

Referenced by skeleton().

Here is the caller graph for this function:

◆ operator=()

EssentialGraph & gum::EssentialGraph::operator= ( const EssentialGraph & g)

Definition at line 65 of file essentialGraph.cpp.

65 {
66 if (&g != this) {
67 _dagmodel_ = g._dagmodel_;
69 }
70 return *this;
71 }

References EssentialGraph(), _buildEssentialGraph_(), and _dagmodel_.

Here is the call graph for this function:

◆ parents() [1/2]

INLINE NodeSet gum::EssentialGraph::parents ( const NodeSet & ids) const

wrapping MixedGraph::parents(ids)

Definition at line 61 of file essentialGraph_inl.h.

61{ return _pdag_.parents(ids); }

References _pdag_.

◆ parents() [2/2]

INLINE const NodeSet & gum::EssentialGraph::parents ( NodeId id) const

wrapping MixedGraph::parents(id)

Definition at line 57 of file essentialGraph_inl.h.

57{ return _pdag_.parents(id); }

References _pdag_.

◆ pdag()

INLINE PDAG gum::EssentialGraph::pdag ( ) const
Returns
a copy of the mixed graph

Definition at line 55 of file essentialGraph_inl.h.

55{ return _pdag_; }

References _pdag_.

◆ size()

INLINE Size gum::EssentialGraph::size ( ) const

wrapping MixedGraph::size()

Definition at line 79 of file essentialGraph_inl.h.

79{ return _pdag_.size(); }

References _pdag_.

◆ sizeArcs()

INLINE Size gum::EssentialGraph::sizeArcs ( ) const

wrapping MixedGraph::sizeArcs()

Definition at line 69 of file essentialGraph_inl.h.

69{ return _pdag_.sizeArcs(); }

References _pdag_.

◆ sizeEdges()

INLINE Size gum::EssentialGraph::sizeEdges ( ) const

wrapping MixedGraph::sizeEdges()

Definition at line 73 of file essentialGraph_inl.h.

73{ return _pdag_.sizeEdges(); }

References _pdag_.

◆ sizeNodes()

INLINE Size gum::EssentialGraph::sizeNodes ( ) const

wrapping MixedGraph::sizeNodes()

Definition at line 77 of file essentialGraph_inl.h.

77{ return _pdag_.sizeNodes(); }

References _pdag_.

◆ skeleton()

UndiGraph gum::EssentialGraph::skeleton ( ) const

Definition at line 177 of file essentialGraph.cpp.

177 {
178 UndiGraph skel;
179 for (const auto& n: nodes())
180 skel.addNodeWithId(n);
181 for (const auto& edge: edges())
182 skel.addEdge(edge.first(), edge.second());
183 for (const auto& arc: arcs())
184 skel.addEdge(arc.tail(), arc.head());
185 return skel;
186 }
const ArcSet & arcs() const
wrapping MixedGraph::arcs()
const NodeGraphPart & nodes() const
wrapping MixedGraph::nodes()
const EdgeSet & edges() const
wrapping MixedGraph::edges()

References gum::UndiGraph::addEdge(), gum::NodeGraphPart::addNodeWithId(), arcs(), edges(), and nodes().

Here is the call graph for this function:

◆ toDot()

std::string gum::EssentialGraph::toDot ( ) const
Returns
a dot representation of this essentialGraph

Definition at line 149 of file essentialGraph.cpp.

149 {
150 std::stringstream output;
151 std::stringstream nodeStream;
152 std::stringstream edgeStream;
153 List< NodeId > treatedNodes;
154 output << "digraph \""
155 << "no_name\" {" << std::endl;
156 nodeStream << "node [shape = ellipse];" << std::endl;
157 std::string tab = " ";
158 if (_dagmodel_ != nullptr) {
159 for (const auto node: _pdag_.nodes()) {
160 nodeStream << tab << node << "[label=\"" << _dagmodel_->variable(node).name() << "\"];";
161
162 for (const auto nei: _pdag_.neighbours(node))
163 if (!treatedNodes.exists(nei))
164 edgeStream << tab << node << " -> " << nei << " [dir=none];" << std::endl;
165
166 for (const auto chi: _pdag_.children(node))
167 edgeStream << tab << node << " -> " << chi << " [color=red];" << std::endl;
168
169 treatedNodes.insert(node);
170 }
171 }
172 output << nodeStream.str() << std::endl << edgeStream.str() << std::endl << "}" << std::endl;
173
174 return output.str();
175 }

References _dagmodel_, _pdag_, gum::List< Val >::exists(), and gum::List< Val >::insert().

Here is the call graph for this function:

Member Data Documentation

◆ _dagmodel_

const DAGmodel* gum::EssentialGraph::_dagmodel_
private

◆ _pdag_


The documentation for this class was generated from the following files: