30 #endif // GUM_NO_INLINE 35 ArcProperty< NodeSet >
41 for (
const auto node : *
__dag)
49 const Size non_barren = std::numeric_limits< Size >::max();
51 observed_anc.insert(node);
52 for (
Idx i = 0; i < observed_anc.size(); ++i) {
53 const NodeId node = observed_anc[i];
55 mark[node] = non_barren;
56 for (
const auto par : __dag->parents(node)) {
57 if (!mark[par] && !observed_anc.exists(par)) {
73 for (
const auto& edge : junction_tree.
edges()) {
79 if (mark[*iter] || separator.
exists(*iter)) { non_barren1.
erase(iter); }
81 result.
insert(
Arc(edge.first(), edge.second()), std::move(non_barren1));
86 if (mark[*iter] || separator.
exists(*iter)) { non_barren2.
erase(iter); }
88 result.
insert(
Arc(edge.second(), edge.first()), std::move(non_barren2));
95 for (
const auto node : *
__dag)
97 for (
const auto& elt : result) {
99 if (!result[arc].empty()) {
103 for (
const auto node : separator) {
104 node2arc[node].
insert(arc);
147 for (
const auto& elt : node2arc) {
148 if (!elt.second.empty()) {
149 nodes_to_mark.
insert(elt.first);
152 while (!nodes_to_mark.
empty()) {
159 for (
auto par : __dag->parents(node)) {
160 Size parent_mark = mark[par];
161 if (parent_mark != std::numeric_limits< Size >::max()) {
163 if (parent_mark == 0) { nodes_to_mark.
insert(par); }
167 if (nb_par == 0) { path_roots.
insert(node); }
174 for (
const auto node : *__dag) {
175 if (mark[node] != 1) { sweep_dag.
eraseNode(node); }
177 for (
const auto node : sweep_dag) {
178 const Size nb_parents = sweep_dag.parents(node).size();
179 const Size nb_children = sweep_dag.children(node).size();
180 if ((nb_parents > 1) || (nb_children > 1)) {
182 const auto& parents = sweep_dag.parents(node);
185 if (nb_children == 0) {
186 auto iter_par = parents.beginSafe();
187 for (++iter_par; iter_par != parents.endSafe(); ++iter_par) {
188 sweep_dag.eraseArc(
Arc(*iter_par, node));
192 const auto& children = sweep_dag.children(node);
193 NodeId smallest_child = 0;
194 Size smallest_nb_par = std::numeric_limits< Size >::max();
195 for (
const auto child : children) {
196 const auto new_nb = sweep_dag.parents(child).size();
197 if (new_nb < smallest_nb_par) {
198 smallest_nb_par = new_nb;
199 smallest_child = child;
205 if (nb_parents == 0) {
206 for (
auto iter = children.beginSafe(); iter != children.endSafe();
208 if (*iter != smallest_child) {
209 if (sweep_dag.parents(*iter).size() == 1) {
212 sweep_dag.eraseArc(
Arc(node, *iter));
216 auto nb_match =
Size(std::min(nb_parents, nb_children) - 1);
217 auto iter_par = parents.beginSafe();
220 auto iter_child = children.beginSafe();
221 for (
Idx i = 0; i < nb_match; ++i, ++iter_par, ++iter_child) {
222 if (*iter_child == smallest_child) { ++iter_child; }
223 sweep_dag.addArc(*iter_par, *iter_child);
224 sweep_dag.eraseArc(
Arc(*iter_par, node));
225 sweep_dag.eraseArc(
Arc(node, *iter_child));
227 for (; iter_par != parents.endSafe(); ++iter_par) {
228 sweep_dag.eraseArc(
Arc(*iter_par, node));
230 for (; iter_child != children.endSafe(); ++iter_child) {
231 if (*iter_child != smallest_child) {
232 if (sweep_dag.parents(*iter_child).size() == 1) {
233 path_roots.
insert(*iter_child);
235 sweep_dag.eraseArc(
Arc(node, *iter_child));
249 for (
NodeId path : path_roots) {
254 while (!to_mark.empty()) {
257 if (mark[node] < mark_id) {
258 mark[node] = mark_id;
259 for (
const auto par : __dag->parents(node)) {
260 if (mark[par] < mark_id) { to_mark.insert(par); }
268 const ArcSet& arcs = node2arc[path];
269 for (
const auto& arc : arcs) {
272 if (mark[*iter] >= mark_id) {
280 const NodeSet& sweep_children = sweep_dag.children(path);
281 if (sweep_children.
size()) {
282 path = *(sweep_children.
begin());
301 int nb_non_barren = 0;
303 nodes_to_examine.
insert(node);
305 nodes_to_examine.
insert(node);
307 while (!nodes_to_examine.
empty()) {
310 if (barren_mark[node]) {
311 barren_mark[node] =
false;
314 nodes_to_examine.
insert(par);
320 for (
const auto& marked_pair : barren_mark)
321 if (marked_pair.second) barren_nodes.
insert(marked_pair.first);
bool empty() const noexcept
Returns a boolean indicating whether the chained list is empty.
const NodeSet & separator(const Edge &edge) const
returns the separator included in a given edge
Size size() const
alias for sizeNodes
Set< Arc > ArcSet
Some typdefs and define for shortcuts ...
const NodeSet * __observed_nodes
the set of observed nodes
NodeProperty< VAL > nodesProperty(VAL(*f)(const NodeId &), Size size=0) const
a method to create a HashTable with key:NodeId and value:VAL
void erase(const Key &k)
Erases an element from the set.
Generic doubly linked lists.
gum is the global namespace for all aGrUM entities
iterator begin() const
The usual unsafe begin iterator to parse the set.
void popFront()
Removes the first element of a List, if any.
NodeId head() const
returns the head of the arc
The class for generic Hash Tables.
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.
const EdgeSet & edges() const
returns the set of edges stored within the EdgeGraphPart
The base class for all directed edgesThis class is used as a basis for manipulating all directed edge...
const NodeSet & parents(const NodeId id) const
returns the set of nodes with arc ingoing to a given node
NodeSet barrenNodes()
returns the set of barren nodes
const NodeSet & clique(const NodeId idClique) const
returns the set of nodes included into a given clique
Size sizeNodes() const
returns the number of nodes in the NodeGraphPart
Val & insert(const Val &val)
Inserts a new element at the end of the chained list (alias of pushBack).
Val & front() const
Returns a reference to first element of a list, if any.
Detect barren nodes for inference in Bayesian networks.
The base class for all undirected edges.
const DAG * __dag
the DAG on which we compute the barren nodes
iterator_safe beginSafe() const
The usual safe begin iterator to parse the set.
const NodeSet * __target_nodes
the set of targeted nodes
Size Idx
Type for indexes.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Size size() const noexcept
Returns the number of elements in the set.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
NodeId first() const
returns one extremal node ID (whichever one it is is unspecified)
virtual void eraseNode(const NodeId id)
remove a node and its adjacent arcs from the graph
Size NodeId
Type for node ids.
void insert(const Key &k)
Inserts a new element into the set.
NodeId tail() const
returns the tail of the arc
void insert(const Key &k)
Insert an element at the end of the sequence.