aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
DAG.cpp
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /** @file
23  * @brief Source implementation of Base classes for directed acyclic graphs
24  *
25  * @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
26  *
27  */
28 #include <agrum/tools/graphs/DAG.h>
29 
30 #ifdef GUM_NO_INLINE
31 # include <agrum/tools/graphs/DAG_inl.h>
32 #endif // GUM_NOINLINE
33 
34 namespace gum {
35 
36  // diamond structure require to explicitly initialize NodeGraphPart
40  bool arcs_resize_policy) :
44  }
45 
46  // diamond structure require to explicitly initialize NodeGraphPart
48 
50 
51 
55  // transform the arcs into edges
56  for (const auto& arc: arcs())
58 
59  // marry the parents
60  for (const auto node: nodes()) {
61  const auto& par = parents(node);
62 
63  for (auto it1 = par.begin(); it1 != par.end(); ++it1) {
64  auto it2 = it1;
65 
66  for (++it2; it2 != par.end(); ++it2) {
67  // will automatically check if this edge already exists
69  }
70  }
71  }
72  return moralgraph;
73  }
74 
75 
77  UndiGraph res;
78  NodeSet tmp{nodes};
79 
80  // findings all nodes
81  while (!tmp.empty()) {
82  auto current = *(tmp.begin());
83  tmp.erase(current);
84 
86  for (auto next: parents(current))
87  if (!tmp.contains(next) && !res.exists(next)) tmp.insert(next);
88  }
89 
90  // finding all edges and moralizing
91  for (auto current: res)
92  for (auto father: parents(current)) {
94  father); // addEdge does not complain if edge already exists
95  for (auto other_father: parents(current))
97  }
98 
99  return res;
100  }
101 
102  bool DAG::dSeparation(NodeId X, NodeId Y, const NodeSet& Z) const {
103  NodeSet cumul{Z};
104  cumul << X << Y;
106  for (auto node: Z)
107  g.eraseNode(node);
108  return !g.hasUndirectedPath(X, Y);
109  }
110 
111  bool
112  DAG::dSeparation(const NodeSet& X, const NodeSet& Y, const NodeSet& Z) const {
113  if (!(X * Y).empty())
115  "NodeSets " << X << ", " << Y << " should have no intersection")
116 
117  NodeSet cumul{Z};
118  cumul += X;
119  cumul += Y;
121  for (auto node: Z)
122  g.eraseNode(node);
123  auto cc = g.nodes2ConnectedComponent();
124 
125  NodeSet Xcc, Ycc;
126  for (const auto node: X)
127  if (g.existsNode(node)) // it may be in Z too
128  if (!Xcc.exists(cc[node])) Xcc.insert(cc[node]);
129  for (const auto node: Y)
130  if (g.existsNode(node)) // it may be in Z too
131  if (!Ycc.exists(cc[node])) Ycc.insert(cc[node]);
132 
133  return (Xcc * Ycc).empty();
134  }
135 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669