aGrUM 3.1.1
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)
NodeSet descendants (NodeId id) const
 wrapping PDAG::descendants(id)
NodeSet ancestors (NodeId id) const
 wrapping PDAG::ancestors(id)
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()
NodeProperty< NodeIdconnectedComponents () const
 Returns the connected components of the essential graph. Each node maps to the id of its component root.
NodeId idFromName (std::string_view 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 76 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
108 for (auto id: _pdag_)
109 _pdag_.setName(id, _dagmodel_->variable(id).name());
110 }
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 116 of file essentialGraph.cpp.

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

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 112 of file essentialGraph.cpp.

112 {
113 return _strongly_protected_(_pdag_, a, b);
114 }

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:

◆ ancestors()

INLINE NodeSet gum::EssentialGraph::ancestors ( NodeId id) const

wrapping PDAG::ancestors(id)

Definition at line 68 of file essentialGraph_inl.h.

68{ return _pdag_.ancestors(id); }

References _pdag_.

◆ arcs()

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

wrapping MixedGraph::arcs()

Definition at line 76 of file essentialGraph_inl.h.

76{ 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 64 of file essentialGraph_inl.h.

64{ 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 60 of file essentialGraph_inl.h.

60{ return _pdag_.children(id); }

References _pdag_.

◆ connectedComponents()

INLINE NodeProperty< NodeId > gum::EssentialGraph::connectedComponents ( ) const

Returns the connected components of the essential graph. Each node maps to the id of its component root.

Definition at line 96 of file essentialGraph_inl.h.

96 {
97 return _pdag_.connectedComponents();
98 }

References _pdag_.

◆ descendants()

INLINE NodeSet gum::EssentialGraph::descendants ( NodeId id) const

wrapping PDAG::descendants(id)

Definition at line 66 of file essentialGraph_inl.h.

66{ return _pdag_.descendants(id); }

References _pdag_.

◆ edges()

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

wrapping MixedGraph::edges()

Definition at line 80 of file essentialGraph_inl.h.

80{ return _pdag_.edges(); }

References _pdag_.

Referenced by skeleton().

Here is the caller graph for this function:

◆ idFromName()

INLINE NodeId gum::EssentialGraph::idFromName ( std::string_view name) const

wrappping DAGModel::idFromName()

Definition at line 88 of file essentialGraph_inl.h.

88 {
89 return _dagmodel_->idFromName(name);
90 }

References _dagmodel_.

◆ nameFromId()

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

wrappping .name()

Definition at line 92 of file essentialGraph_inl.h.

92 {
93 return _dagmodel_->variable(node).name();
94 }

References _dagmodel_.

◆ neighbours()

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

wrapping MixedGraph::parents(id)

Definition at line 70 of file essentialGraph_inl.h.

70 {
71 return _pdag_.neighbours(id);
72 }

References _pdag_.

◆ nodes()

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

wrapping MixedGraph::nodes()

Definition at line 86 of file essentialGraph_inl.h.

86{ 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 62 of file essentialGraph_inl.h.

62{ 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 58 of file essentialGraph_inl.h.

58{ return _pdag_.parents(id); }

References _pdag_.

◆ pdag()

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

Definition at line 56 of file essentialGraph_inl.h.

56{ return _pdag_; }

References _pdag_.

◆ size()

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

wrapping MixedGraph::size()

Definition at line 84 of file essentialGraph_inl.h.

84{ return _pdag_.size(); }

References _pdag_.

◆ sizeArcs()

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

wrapping MixedGraph::sizeArcs()

Definition at line 74 of file essentialGraph_inl.h.

74{ return _pdag_.sizeArcs(); }

References _pdag_.

◆ sizeEdges()

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

wrapping MixedGraph::sizeEdges()

Definition at line 78 of file essentialGraph_inl.h.

78{ return _pdag_.sizeEdges(); }

References _pdag_.

◆ sizeNodes()

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

wrapping MixedGraph::sizeNodes()

Definition at line 82 of file essentialGraph_inl.h.

82{ return _pdag_.sizeNodes(); }

References _pdag_.

◆ skeleton()

UndiGraph gum::EssentialGraph::skeleton ( ) const

Definition at line 182 of file essentialGraph.cpp.

182 {
183 UndiGraph skel;
184 for (const auto& n: nodes())
185 skel.addNodeWithId(n);
186 for (const auto& edge: edges())
187 skel.addEdge(edge.first(), edge.second());
188 for (const auto& arc: arcs())
189 skel.addEdge(arc.tail(), arc.head());
190 if (_dagmodel_ != nullptr)
191 for (auto id: skel)
192 skel.setName(id, _dagmodel_->variable(id).name());
193 return skel;
194 }
const ArcSet & arcs() const
wrapping MixedGraph::arcs()
const NodeGraphPart & nodes() const
wrapping MixedGraph::nodes()
const EdgeSet & edges() const
wrapping MixedGraph::edges()

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

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 152 of file essentialGraph.cpp.

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

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: