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
37
DAG
::
DAG
(
Size
nodes_size
,
38
bool
nodes_resize_policy
,
39
Size
arcs_size
,
40
bool
arcs_resize_policy
) :
41
NodeGraphPart
(
nodes_size
,
nodes_resize_policy
),
42
DiGraph
(
nodes_size
,
nodes_resize_policy
,
arcs_size
,
arcs_resize_policy
) {
43
GUM_CONSTRUCTOR
(
DAG
);
44
}
45
46
// diamond structure require to explicitly initialize NodeGraphPart
47
DAG
::
DAG
(
const
DAG
&
g
) :
NodeGraphPart
(
g
),
DiGraph
(
g
) {
GUM_CONS_CPY
(
DAG
); }
48
49
DAG
::~
DAG
() {
GUM_DESTRUCTOR
(
DAG
); }
50
51
52
UndiGraph
DAG
::
moralGraph
()
const
{
53
UndiGraph
moralgraph
;
54
moralgraph
.
populateNodes
(*
this
);
55
// transform the arcs into edges
56
for
(
const
auto
&
arc
:
arcs
())
57
moralgraph
.
addEdge
(
arc
.
first
(),
arc
.
second
());
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
68
moralgraph
.
addEdge
(*
it1
, *
it2
);
69
}
70
}
71
}
72
return
moralgraph
;
73
}
74
75
76
UndiGraph
DAG
::
moralizedAncestralGraph
(
const
NodeSet
&
nodes
)
const
{
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
85
res
.
addNodeWithId
(
current
);
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
)) {
93
res
.
addEdge
(
current
,
94
father
);
// addEdge does not complain if edge already exists
95
for
(
auto
other_father
:
parents
(
current
))
96
if
(
other_father
!=
father
)
res
.
addEdge
(
father
,
other_father
);
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
;
105
auto
g
=
moralizedAncestralGraph
(
cumul
);
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
())
114
GUM_ERROR
(
InvalidArgument
,
115
"NodeSets "
<<
X
<<
", "
<<
Y
<<
" should have no intersection"
)
116
117
NodeSet
cumul
{
Z
};
118
cumul
+=
X
;
119
cumul
+=
Y
;
120
auto
g
=
moralizedAncestralGraph
(
cumul
);
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 */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:669