aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
DAG.cpp
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by 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
41  }
42 
43  // diamond structure require to explicitly initialize NodeGraphPart
44  DAG::DAG(const DAG& g) : NodeGraphPart(g), DiGraph(g) {
46  ;
47  }
48 
49  DAG::~DAG() {
51  ;
52  }
53 
54 
58  // transform the arcs into edges
59  for (const auto& arc: arcs())
61 
62  // marry the parents
63  for (const auto node: nodes()) {
64  const auto& par = parents(node);
65 
66  for (auto it1 = par.begin(); it1 != par.end(); ++it1) {
67  auto it2 = it1;
68 
69  for (++it2; it2 != par.end(); ++it2) {
70  // will automatically check if this edge already exists
72  }
73  }
74  }
75  return moralgraph;
76  }
77 
78 
80  UndiGraph res;
81  NodeSet tmp{nodes};
82 
83  // findings all nodes
84  while (!tmp.empty()) {
85  auto current = *(tmp.begin());
86  tmp.erase(current);
87 
89  for (auto next: parents(current))
90  if (!tmp.contains(next) && !res.exists(next)) tmp.insert(next);
91  }
92 
93  // finding all edges and moralizing
94  for (auto current: res)
95  for (auto father: parents(current)) {
97  father); // addEdge does not complain if edge already exists
98  for (auto other_father: parents(current))
100  }
101 
102  return res;
103  }
104 
105  bool DAG::dSeparation(NodeId X, NodeId Y, const NodeSet& Z) const {
106  NodeSet cumul{Z};
107  cumul << X << Y;
109  for (auto node: Z)
110  g.eraseNode(node);
111  return !g.hasUndirectedPath(X, Y);
112  }
113 
114  bool DAG::dSeparation(const NodeSet& X, const NodeSet& Y, const NodeSet& Z) const {
115  if (!(X * Y).empty())
116  GUM_ERROR(InvalidArgument, "NodeSets " << X << ", " << Y << " should have no intersection")
117 
118  NodeSet cumul{Z};
119  cumul += X;
120  cumul += Y;
122  for (auto node: Z)
123  g.eraseNode(node);
124  auto cc = g.nodes2ConnectedComponent();
125 
126  NodeSet Xcc, Ycc;
127  for (const auto node: X)
128  if (g.existsNode(node)) // it may be in Z too
129  if (!Xcc.exists(cc[node])) Xcc.insert(cc[node]);
130  for (const auto node: Y)
131  if (g.existsNode(node)) // it may be in Z too
132  if (!Ycc.exists(cc[node])) Ycc.insert(cc[node]);
133 
134  return (Xcc * Ycc).empty();
135  }
136 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643