aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
cliqueGraph_inl.h
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 inline source of basic clique graphs
24
*
25
* @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
26
*/
27
28
#
ifndef
DOXYGEN_SHOULD_SKIP_THIS
29
30
// to ease parser in IDE
31
#
include
<
agrum
/
tools
/
graphs
/
cliqueGraph
.
h
>
32
33
namespace
gum
{
34
35
/// copy operator
36
INLINE CliqueGraph&
CliqueGraph
::
operator
=(
const
CliqueGraph
&
g
) {
37
if
(
this
!= &
g
) {
38
UndiGraph
::
operator
=(
g
);
39
_cliques_
=
g
.
_cliques_
;
40
_separators_
=
g
.
_separators_
;
41
}
42
43
return
*
this
;
44
}
45
46
INLINE
void
CliqueGraph
::
addEdge
(
const
NodeId
first
,
const
NodeId
second
) {
47
Edge
edge
(
first
,
second
);
48
49
if
(!
existsEdge
(
edge
)) {
50
// create the edge in the graph
51
UndiGraph
::
addEdge
(
first
,
second
);
52
53
// create the separator
54
_separators_
.
insert
(
edge
,
_cliques_
[
first
] *
_cliques_
[
second
]);
55
}
56
}
57
58
/// removes an edge (and its separator) from the clique graph
59
60
INLINE
void
CliqueGraph
::
eraseEdge
(
const
Edge
&
edge
) {
61
if
(
existsEdge
(
edge
)) {
62
_separators_
.
erase
(
edge
);
63
UndiGraph
::
eraseEdge
(
edge
);
64
}
65
}
66
67
/// adds a new clique to the graph
68
69
INLINE
NodeId
CliqueGraph
::
addNode
(
const
NodeSet
&
clique
) {
70
// create the new node in the graph
71
NodeId
new_node
=
UndiGraph
::
addNode
();
72
73
// update the set of nodes of the clique
74
_cliques_
.
insert
(
new_node
,
clique
);
75
return
new_node
;
76
}
77
78
INLINE
NodeId
CliqueGraph
::
addNode
() {
return
addNode
(
NodeSet
()); }
79
80
/// adds a new clique to the graph
81
82
INLINE
void
CliqueGraph
::
addNode
(
const
NodeId
id
,
const
NodeSet
&
clique
) {
83
// create the new node in the graph
84
UndiGraph
::
addNodeWithId
(
id
);
85
86
// update the set of nodes of the clique
87
_cliques_
.
insert
(
id
,
clique
);
88
}
89
90
INLINE
void
CliqueGraph
::
addNode
(
const
NodeId
id
) {
addNode
(
id
,
NodeSet
()); }
91
92
/// removes a given clique from the clique graph
93
94
INLINE
void
CliqueGraph
::
eraseNode
(
const
NodeId
id
) {
95
// check if the node belongs to the graph
96
if
(!
exists
(
id
))
return
;
97
98
// remove the separators
99
auto
nei
=
neighbours
(
id
);
100
for
(
auto
iter
=
nei
.
beginSafe
();
iter
!=
nei
.
endSafe
(); ++
iter
)
// safe iterator needed here
101
eraseEdge
(
Edge
(*
iter
,
id
));
102
103
// erase the clique set
104
_cliques_
.
erase
(
id
);
105
106
// erase the node and its neighbours from the graph
107
UndiGraph
::
eraseNode
(
id
);
108
}
109
110
/// returns the set of nodes included into a given clique
111
112
INLINE
const
NodeSet
&
CliqueGraph
::
clique
(
const
NodeId
clique
)
const
{
return
_cliques_
[
clique
]; }
113
114
/// returns the id of a clique containing the node the id of which is in
115
/// argument
116
117
INLINE
NodeId
CliqueGraph
::
container
(
const
NodeId
id
)
const
{
118
for
(
const
auto
&
elt
:
_cliques_
)
119
if
(
elt
.
second
.
contains
(
id
))
return
elt
.
first
;
120
121
GUM_ERROR
(
NotFound
,
"This node belongs to no clique"
)
122
}
123
124
/// function used to update the _separators_ when _clique_/edges are modified
125
126
INLINE
void
CliqueGraph
::
_updateSeparators_
(
const
NodeId
id1
) {
127
for
(
const
auto
nei
:
neighbours
(
id1
))
128
_separators_
[
Edge
(
nei
,
id1
)] =
_cliques_
[
id1
] *
_cliques_
[
nei
];
129
}
130
131
/// changes the set of nodes included into a given clique and returns the new
132
/// set
133
134
INLINE
void
CliqueGraph
::
setClique
(
const
NodeId
id
,
const
NodeSet
&
new_clique
) {
135
// get the current clique set
136
_cliques_
[
id
] =
new_clique
;
137
_updateSeparators_
(
id
);
138
}
139
140
/// returns the separator included in a given edge
141
142
INLINE
const
NodeSet
&
CliqueGraph
::
separator
(
const
Edge
&
edge
)
const
{
143
return
_separators_
[
edge
];
144
}
145
146
/// returns the separator included in an edge specified by its extremities
147
148
INLINE
const
NodeSet
&
CliqueGraph
::
separator
(
const
NodeId
node1
,
const
NodeId
node2
)
const
{
149
return
separator
(
Edge
(
node1
,
node2
));
150
}
151
152
/// indicates whether the graph is a join tree
153
154
INLINE
bool
CliqueGraph
::
isJoinTree
()
const
{
155
return
(!
hasUndirectedCycle
() &&
hasRunningIntersection
());
156
}
157
158
/// removes all the nodes from the graph (as well as their adjacent
159
/// edges/arcs)
160
161
INLINE
void
CliqueGraph
::
clear
() {
162
UndiGraph
::
clear
();
163
_cliques_
.
clear
();
164
_separators_
.
clear
();
165
}
166
167
/// removes all the edges from the clique graph
168
169
INLINE
void
CliqueGraph
::
clearEdges
() {
170
UndiGraph
::
clearEdges
();
171
_separators_
.
clear
();
172
}
173
174
/// checks whether two clique graphs are different
175
176
INLINE
bool
CliqueGraph
::
operator
!=(
const
CliqueGraph
&
from
)
const
{
return
(!
operator
==(
from
)); }
177
178
}
/* namespace gum */
179
180
#
endif
/* DOXYGEN_SHOULD_SKIP_THIS */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643