aGrUM
0.20.2
a C++ library for (probabilistic) graphical models
multiDimFunctionGraphGenerator.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
/**
23
* @file
24
* @brief Sources of MultiDimFunctionGraphGenerator.
25
*
26
* @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
27
* @author Pierre-Henri WUILLEMIN(@LIP6) and Jean-Christophe MAGNAN and Christophe
28
* GONZALES(@AMU)
29
*
30
*/
31
32
#
include
<
cstdlib
>
33
#
include
<
random
>
34
35
#
include
<
agrum
/
tools
/
core
/
priorityQueue
.
h
>
36
#
include
<
agrum
/
tools
/
multidim
/
implementations
/
multiDimFunctionGraphGenerator
.
h
>
37
38
namespace
gum
{
39
// Constructor
40
MultiDimFunctionGraphGenerator
::
MultiDimFunctionGraphGenerator
(
41
Idx
maxVar
,
42
Idx
minVar
,
43
const
Sequence
<
const
DiscreteVariable
* >&
varSeq
) :
44
varSeq__
(
varSeq
) {
45
GUM_CONSTRUCTOR
(
MultiDimFunctionGraphGenerator
);
46
47
nbTotalVar__
=
varSeq__
.
size
();
48
}
49
50
// Destructor
51
MultiDimFunctionGraphGenerator
::~
MultiDimFunctionGraphGenerator
() {
52
GUM_DESTRUCTOR
(
MultiDimFunctionGraphGenerator
);
53
}
54
55
MultiDimFunctionGraph
<
double
>*
MultiDimFunctionGraphGenerator
::
generate
() {
56
MultiDimFunctionGraph
<
double
>*
generatedFunctionGraph
57
=
MultiDimFunctionGraph
<
double
>::
getReducedAndOrderedInstance
();
58
59
for
(
SequenceIteratorSafe
<
const
DiscreteVariable
* >
varIter
60
=
varSeq__
.
beginSafe
();
61
varIter
!=
varSeq__
.
endSafe
();
62
++
varIter
) {
63
generatedFunctionGraph
->
add
(**
varIter
);
64
}
65
66
HashTable
<
NodeId
,
Idx
>
node2MinVar
;
67
Idx
nbIter
= 0;
68
69
std
::
vector
<
NodeId
>
filo
;
70
71
generatedFunctionGraph
->
manager
()->
setRootNode
(
72
generatedFunctionGraph
->
manager
()->
addInternalNode
(
varSeq__
.
atPos
(0)));
73
node2MinVar
.
insert
(
generatedFunctionGraph
->
root
(), 0);
74
filo
.
push_back
(
generatedFunctionGraph
->
root
());
75
76
while
(!
filo
.
empty
()) {
//&& nbIter < 20 ){
77
78
NodeId
currentNodeId
=
filo
.
back
();
79
filo
.
pop_back
();
80
Idx
cvp
=
node2MinVar
[
currentNodeId
];
81
const
InternalNode
*
currentNode
82
=
generatedFunctionGraph
->
node
(
currentNodeId
);
83
84
LinkedList
<
NodeId
>
potentialSons
;
85
Idx
nbPotentialSons
= 0;
86
for
(
Idx
varPos
= 0;
87
varPos
<
generatedFunctionGraph
->
variablesSequence
().
size
();
88
varPos
++) {
89
const
DiscreteVariable
*
var
90
=
generatedFunctionGraph
->
variablesSequence
().
atPos
(
varPos
);
91
92
Idx
vsp
=
varSeq__
.
pos
(
var
);
93
if
(
vsp
>
cvp
) {
94
const
Link
<
NodeId
>*
nicleIter
95
=
generatedFunctionGraph
->
varNodeListe
(
var
)->
list
();
96
while
(
nicleIter
) {
97
nbPotentialSons
++;
98
potentialSons
.
addLink
(
nicleIter
->
element
());
99
nicleIter
=
nicleIter
->
nextLink
();
100
}
101
}
102
}
103
104
for
(
Idx
modality
= 0;
modality
<
currentNode
->
nodeVar
()->
domainSize
();
105
modality
++) {
106
if
(!
potentialSons
.
list
()
107
|| (
double
)
std
::
rand
() / (
double
)RAND_MAX
108
> (1.0 / (1.0 + 3.0 /
nbPotentialSons
))) {
109
if
(
createLeaf__
(
currentNodeId
,
node2MinVar
)) {
110
generatedFunctionGraph
->
manager
()->
setSon
(
111
currentNodeId
,
112
modality
,
113
generatedFunctionGraph
->
manager
()->
addTerminalNode
(
114
(
double
)
std
::
rand
() / (
double
)RAND_MAX * 100));
115
}
else
{
116
Idx
sonVarPos
117
=
generateVarPos__
(
node2MinVar
[
currentNodeId
] + 1,
118
nbTotalVar__
-
node2MinVar
[
currentNodeId
] - 2);
119
generatedFunctionGraph
->
manager
()->
setSon
(
120
currentNodeId
,
121
modality
,
122
generatedFunctionGraph
->
manager
()->
addInternalNode
(
123
varSeq__
.
atPos
(
sonVarPos
)));
124
filo
.
push_back
(
currentNode
->
son
(
modality
));
125
node2MinVar
.
insert
(
currentNode
->
son
(
modality
),
sonVarPos
);
126
}
127
}
else
{
128
Idx
sonPos
129
= (
Idx
)(((
double
)
std
::
rand
() / (
double
)RAND_MAX) *
nbPotentialSons
);
130
sonPos
=
sonPos
==
nbPotentialSons
?
nbPotentialSons
- 1 :
sonPos
;
131
Link
<
NodeId
>*
nicleIter
=
potentialSons
.
list
();
132
while
(
sonPos
) {
133
nicleIter
=
nicleIter
->
nextLink
();
134
sonPos
--;
135
}
136
generatedFunctionGraph
->
manager
()->
setSon
(
currentNodeId
,
137
modality
,
138
nicleIter
->
element
());
139
}
140
}
141
++
nbIter
;
142
}
143
144
generatedFunctionGraph
->
manager
()->
reduce
();
145
generatedFunctionGraph
->
manager
()->
clean
();
146
147
return
generatedFunctionGraph
;
148
}
149
150
bool
MultiDimFunctionGraphGenerator
::
createLeaf__
(
151
NodeId
currentNodeId
,
152
HashTable
<
NodeId
,
Idx
>&
node2MinVar
) {
153
return
!(
currentNodeId
== 1
154
|| ((
double
)
std
::
rand
() / (
double
)RAND_MAX
155
< 0.9
156
+ 0.01
157
* (
float
(
nbTotalVar__
-
node2MinVar
[
currentNodeId
])
158
/
float
(
nbTotalVar__
))
159
&&
node2MinVar
[
currentNodeId
] <
nbTotalVar__
- 1));
160
}
161
162
Idx
MultiDimFunctionGraphGenerator
::
generateVarPos__
(
Idx
offset
,
Idx
span
) {
163
Idx
randOut
= 0;
164
165
if
(
span
!= 0) {
166
auto
generator
=
gum
::
getRandomGenerator
();
167
std
::
weibull_distribution
<
double
>
distribution
(
double
(
span
), 1.0);
168
randOut
= (
Idx
)(
distribution
(
generator
) *
span
/ 2);
169
if
(
randOut
>
span
)
randOut
=
span
;
170
}
171
172
return
offset
+
randOut
;
173
}
174
175
}
// namespace gum
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:669