aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
edgeGraphPart.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 classes for undirected edge sets
24
*
25
* @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
26
*
27
*/
28
#
include
<
agrum
/
tools
/
graphs
/
parts
/
edgeGraphPart
.
h
>
29
30
#
ifdef
GUM_NO_INLINE
31
#
include
<
agrum
/
tools
/
graphs
/
parts
/
edgeGraphPart_inl
.
h
>
32
#
endif
// GUM_NOINLINE
33
#
include
"agrum/tools/graphs/graphElements.h"
34
35
namespace
gum
{
36
37
///////////////////// EdgeGraphPart
38
EdgeGraphPart
::
EdgeGraphPart
(
Size
edges_size
,
bool
edges_resize_policy
) :
39
_edges_
(
edges_size
,
edges_resize_policy
) {
40
GUM_CONSTRUCTOR
(
EdgeGraphPart
);
41
}
42
43
EdgeGraphPart
::
EdgeGraphPart
(
const
EdgeGraphPart
&
s
) :
_edges_
(
s
.
_edges_
) {
44
GUM_CONS_CPY
(
EdgeGraphPart
);
45
46
// copy the set of neighbours
47
_neighbours_
.
resize
(
s
.
_neighbours_
.
capacity
());
48
49
for
(
const
auto
&
elt
:
s
.
_neighbours_
) {
50
NodeSet
*
newneigh
=
new
NodeSet
(*
elt
.
second
);
51
_neighbours_
.
insert
(
elt
.
first
,
newneigh
);
52
}
53
54
// send signals to indicate that there are new edges
55
if
(
onEdgeAdded
.
hasListener
())
56
for
(
const
auto
&
edge
:
_edges_
)
57
GUM_EMIT2
(
onEdgeAdded
,
edge
.
first
(),
edge
.
second
());
58
}
59
60
EdgeGraphPart
::~
EdgeGraphPart
() {
61
GUM_DESTRUCTOR
(
EdgeGraphPart
);
62
// be sure to deallocate all the neighbours sets
63
clearEdges
();
64
}
65
66
void
EdgeGraphPart
::
clearEdges
() {
67
for
(
const
auto
&
elt
:
_neighbours_
)
68
delete
elt
.
second
;
69
70
_neighbours_
.
clear
();
71
72
if
(
onEdgeDeleted
.
hasListener
()) {
73
EdgeSet
tmp
=
_edges_
;
74
_edges_
.
clear
();
75
76
for
(
const
auto
&
edge
:
tmp
)
77
GUM_EMIT2
(
onEdgeDeleted
,
edge
.
first
(),
edge
.
second
());
78
}
else
{
79
_edges_
.
clear
();
80
}
81
}
82
83
EdgeGraphPart
&
EdgeGraphPart
::
operator
=(
const
EdgeGraphPart
&
s
) {
84
// avoid self assignment
85
if
(
this
!= &
s
) {
86
clearEdges
();
87
88
_edges_
=
s
.
_edges_
;
89
90
// copy the set of neighbours
91
_neighbours_
.
resize
(
s
.
_neighbours_
.
capacity
());
92
93
for
(
const
auto
&
elt
:
s
.
_neighbours_
) {
94
NodeSet
*
newneigh
=
new
NodeSet
(*
elt
.
second
);
95
_neighbours_
.
insert
(
elt
.
first
,
newneigh
);
96
}
97
98
if
(
onEdgeAdded
.
hasListener
())
99
for
(
const
auto
&
edge
:
_edges_
)
100
GUM_EMIT2
(
onEdgeAdded
,
edge
.
first
(),
edge
.
second
());
101
}
102
103
return
*
this
;
104
}
105
106
std
::
string
EdgeGraphPart
::
toString
()
const
{
107
std
::
stringstream
s
;
108
bool
first
=
true
;
109
s
<<
"{"
;
110
111
for
(
const
auto
&
edge
:
_edges_
) {
112
if
(
first
)
113
first
=
false
;
114
else
115
s
<<
","
;
116
117
s
<<
edge
;
118
}
119
120
s
<<
"}"
;
121
122
return
s
.
str
();
123
}
124
125
const
std
::
vector
<
NodeId
>
EdgeGraphPart
::
undirectedPath
(
const
NodeId
n1
,
126
const
NodeId
n2
)
const
{
127
// not recursive version => use a FIFO for simulating the recursion
128
List
<
NodeId
>
nodeFIFO
;
129
nodeFIFO
.
pushBack
(
n2
);
130
131
// mark[node] = predecessor if visited, else mark[node] does not exist
132
NodeProperty
<
NodeId
>
mark
;
133
mark
.
insert
(
n2
,
n2
);
134
135
NodeId
current
;
136
137
while
(!
nodeFIFO
.
empty
()) {
138
current
=
nodeFIFO
.
front
();
139
nodeFIFO
.
popFront
();
140
141
// check the neighbour
142
for
(
const
auto
new_one
:
neighbours
(
current
)) {
143
if
(
mark
.
exists
(
new_one
))
// if this node is already marked, stop
144
continue
;
145
146
mark
.
insert
(
new_one
,
current
);
147
148
if
(
new_one
==
n1
) {
149
std
::
vector
<
NodeId
>
v
;
150
151
for
(
current
=
n1
;
current
!=
n2
;
current
=
mark
[
current
])
152
v
.
push_back
(
current
);
153
154
v
.
push_back
(
n2
);
155
156
return
v
;
157
}
158
159
nodeFIFO
.
pushBack
(
new_one
);
160
}
161
}
162
163
GUM_ERROR
(
NotFound
,
"no path found"
)
164
}
165
166
bool
EdgeGraphPart
::
hasUndirectedPath
(
NodeId
n1
,
NodeId
n2
)
const
{
167
NodeSet
visited
;
168
NodeSet
temp
;
169
170
temp
.
insert
(
n1
);
171
while
(!
temp
.
empty
()) {
172
NodeId
current
= *(
temp
.
begin
());
173
if
(
current
==
n2
)
return
true
;
174
temp
.
erase
(
current
);
175
visited
.
insert
(
current
);
176
for
(
auto
next
:
neighbours
(
current
)) {
177
if
(!
temp
.
contains
(
next
) && !
visited
.
contains
(
next
))
temp
.
insert
(
next
);
178
}
179
}
180
return
false
;
181
}
182
183
bool
EdgeGraphPart
::
hasUndirectedPath
(
NodeId
n1
,
const
NodeId
n2
,
const
NodeSet
&
except
)
const
{
184
NodeSet
visited
;
185
NodeSet
temp
;
186
187
if
(
except
.
contains
(
n2
))
return
false
;
188
189
temp
.
insert
(
n1
);
190
while
(!
temp
.
empty
()) {
191
NodeId
current
= *(
temp
.
begin
());
192
if
(
current
==
n2
)
return
true
;
193
temp
.
erase
(
current
);
194
visited
.
insert
(
current
);
195
for
(
auto
next
:
neighbours
(
current
)) {
196
if
(!
temp
.
contains
(
next
) && !
visited
.
contains
(
next
) && !
except
.
contains
(
next
))
197
temp
.
insert
(
next
);
198
}
199
}
200
return
false
;
201
}
202
203
bool
EdgeGraphPart
::
hasUndirectedPath
(
const
NodeSet
&
n1
,
204
const
NodeSet
&
n2
,
205
const
NodeSet
&
except
)
const
{
206
NodeSet
visited
;
207
NodeSet
temp
;
208
209
for
(
auto
n
:
n1
)
210
temp
.
insert
(
n
);
211
212
while
(!
temp
.
empty
()) {
213
NodeId
current
= *(
temp
.
begin
());
214
if
(
n2
.
contains
(
current
))
return
true
;
215
temp
.
erase
(
current
);
216
visited
.
insert
(
current
);
217
for
(
auto
next
:
neighbours
(
current
)) {
218
if
(!
temp
.
contains
(
next
) && !
visited
.
contains
(
next
) && !
except
.
contains
(
next
))
219
temp
.
insert
(
next
);
220
}
221
}
222
return
false
;
223
}
224
225
std
::
ostream
&
operator
<<(
std
::
ostream
&
stream
,
const
EdgeGraphPart
&
set
) {
226
stream << set.toString();
227
return
stream;
228
}
229
230
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643
gum::operator<<
std::ostream & operator<<(std::ostream &aStream, const Instantiation &i)
Print information of the instantiation in the stream.
Definition:
instantiation.cpp:247