62 for (
const auto node: *
_dag_)
70 const Size non_barren = std::numeric_limits< Size >::max();
73 for (
Idx i = 0; i < observed_anc.
size(); ++i) {
74 const NodeId node = observed_anc[i];
76 mark[node] = non_barren;
77 for (
const auto par:
_dag_->parents(node)) {
78 if (!mark[par] && !observed_anc.
exists(par)) { observed_anc.
insert(par); }
92 for (
const auto& edge: junction_tree.
edges()) {
96 for (
auto iter = non_barren1.
beginSafe(); iter != non_barren1.
endSafe(); ++iter) {
97 if (mark[*iter] || separator.
exists(*iter)) { non_barren1.
erase(iter); }
99 result.
insert(
Arc(edge.first(), edge.second()), std::move(non_barren1));
102 for (
auto iter = non_barren2.
beginSafe(); iter != non_barren2.
endSafe(); ++iter) {
103 if (mark[*iter] || separator.
exists(*iter)) { non_barren2.
erase(iter); }
105 result.
insert(
Arc(edge.second(), edge.first()), std::move(non_barren2));
112 for (
const auto node: *
_dag_)
114 for (
const auto& elt: result) {
116 if (!result[arc].empty()) {
120 for (
const auto node: separator) {
121 node2arc[node].
insert(arc);
164 for (
const auto& elt: node2arc) {
165 if (!elt.second.empty()) {
166 nodes_to_mark.
insert(elt.first);
169 while (!nodes_to_mark.
empty()) {
176 for (
auto par:
_dag_->parents(node)) {
177 Size parent_mark = mark[par];
178 if (parent_mark != std::numeric_limits< Size >::max()) {
180 if (parent_mark == 0) { nodes_to_mark.
insert(par); }
184 if (nb_par == 0) { path_roots.
insert(node); }
191 for (
const auto node: *
_dag_) {
192 if (mark[node] != 1) { sweep_dag.
eraseNode(node); }
194 for (
const auto node: sweep_dag) {
197 if ((nb_parents > 1) || (nb_children > 1)) {
199 const auto& parents = sweep_dag.
parents(node);
202 if (nb_children == 0) {
203 auto iter_par = parents.beginSafe();
204 for (++iter_par; iter_par != parents.endSafe(); ++iter_par) {
209 const auto& children = sweep_dag.
children(node);
210 NodeId smallest_child = 0;
211 Size smallest_nb_par = std::numeric_limits< Size >::max();
212 for (
const auto child: children) {
213 const auto new_nb = sweep_dag.
parents(child).
size();
214 if (new_nb < smallest_nb_par) {
215 smallest_nb_par = new_nb;
216 smallest_child = child;
222 if (nb_parents == 0) {
223 for (
auto iter = children.beginSafe(); iter != children.endSafe(); ++iter) {
224 if (*iter != smallest_child) {
230 auto nb_match =
Size(std::min(nb_parents, nb_children) - 1);
231 auto iter_par = parents.beginSafe();
234 auto iter_child = children.beginSafe();
235 for (
Idx i = 0; i < nb_match; ++i, ++iter_par, ++iter_child) {
236 if (*iter_child == smallest_child) { ++iter_child; }
237 sweep_dag.
addArc(*iter_par, *iter_child);
241 for (; iter_par != parents.endSafe(); ++iter_par) {
244 for (; iter_child != children.endSafe(); ++iter_child) {
245 if (*iter_child != smallest_child) {
246 if (sweep_dag.
parents(*iter_child).
size() == 1) { path_roots.
insert(*iter_child); }
261 for (
NodeId path: path_roots) {
266 while (!to_mark.
empty()) {
269 if (mark[node] < mark_id) {
270 mark[node] = mark_id;
271 for (
const auto par:
_dag_->parents(node)) {
272 if (mark[par] < mark_id) { to_mark.
insert(par); }
280 const ArcSet& arcs = node2arc[path];
281 for (
const auto& arc: arcs) {
284 if (mark[*iter] >= mark_id) {
293 if (sweep_children.
size()) {
294 path = *(sweep_children.
begin());
313 int nb_non_barren = 0;
315 nodes_to_examine.
insert(node);
317 nodes_to_examine.
insert(node);
319 while (!nodes_to_examine.
empty()) {
322 if (barren_mark[node]) {
323 barren_mark[node] =
false;
325 for (
const auto par:
_dag_->parents(node))
326 nodes_to_examine.
insert(par);
331 NodeSet barren_nodes(
_dag_->sizeNodes() - nb_non_barren);
332 for (
const auto& marked_pair: barren_mark)
333 if (marked_pair.second) barren_nodes.
insert(marked_pair.first);
Detect barren nodes for inference in Bayesian networks.
const NodeSet & parents(NodeId id) const
returns the set of nodes with arc ingoing to a given node
NodeSet children(const NodeSet &ids) const
returns the set of children of a set of nodes
virtual void eraseArc(const Arc &arc)
removes an arc from the ArcGraphPart
The base class for all directed edges.
GUM_NODISCARD NodeId head() const
returns the head of the arc
GUM_NODISCARD NodeId first() const
returns one extremal node ID (whichever one it is is unspecified)
GUM_NODISCARD NodeId tail() const
returns the tail of the arc
const NodeSet * _observed_nodes_
the set of observed nodes
const DAG * _dag_
the DAG on which we compute the barren nodes
NodeSet barrenNodes()
returns the set of barren nodes
const NodeSet * _target_nodes_
the set of targeted nodes
const NodeSet & separator(const Edge &edge) const
returns the separator included in a given edge
const NodeSet & clique(const NodeId idClique) const
returns the set of nodes included into a given clique
void addArc(NodeId tail, NodeId head) final
insert a new arc into the directed graph
virtual void eraseNode(const NodeId id)
remove a node and its adjacent arcs from the graph
const EdgeSet & edges() const
returns the set of edges stored within the EdgeGraphPart
The base class for all undirected edges.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
Generic doubly linked lists.
Val & front() const
Returns a reference to first element of a list, if any.
bool empty() const noexcept
Returns a boolean indicating whether the chained list is empty.
void popFront()
Removes the first element of a List, if any.
Val & insert(const Val &val)
Inserts a new element at the end of the chained list (alias of pushBack).
Size size() const noexcept
bool exists(const Key &k) const
void insert(const Key &k)
iterator begin() const
The usual unsafe begin iterator to parse the set.
Size size() const noexcept
Returns the number of elements in the set.
iterator_safe beginSafe() const
The usual safe begin iterator to parse the set.
const iterator_safe & endSafe() const noexcept
The usual safe end iterator to parse the set.
bool exists(const Key &k) const
Indicates whether a given elements belong to the set.
void insert(const Key &k)
Inserts a new element into the set.
void erase(const Key &k)
Erases an element from the set.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Size Idx
Type for indexes.
Size NodeId
Type for node ids.
HashTable< Arc, VAL > ArcProperty
Property on graph elements.
Set< Arc > ArcSet
Some typdefs and define for shortcuts ...
HashTable< NodeId, VAL > NodeProperty
Property on graph elements.
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
gum is the global namespace for all aGrUM entities