aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
multiDimFunctionGraphGenerator.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
/**
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
=
_varSeq_
.
beginSafe
();
60
varIter
!=
_varSeq_
.
endSafe
();
61
++
varIter
) {
62
generatedFunctionGraph
->
add
(**
varIter
);
63
}
64
65
HashTable
<
NodeId
,
Idx
>
node2MinVar
;
66
Idx
nbIter
= 0;
67
68
std
::
vector
<
NodeId
>
filo
;
69
70
generatedFunctionGraph
->
manager
()->
setRootNode
(
71
generatedFunctionGraph
->
manager
()->
addInternalNode
(
_varSeq_
.
atPos
(0)));
72
node2MinVar
.
insert
(
generatedFunctionGraph
->
root
(), 0);
73
filo
.
push_back
(
generatedFunctionGraph
->
root
());
74
75
while
(!
filo
.
empty
()) {
//&& nbIter < 20 ){
76
77
NodeId
currentNodeId
=
filo
.
back
();
78
filo
.
pop_back
();
79
Idx
cvp
=
node2MinVar
[
currentNodeId
];
80
const
InternalNode
*
currentNode
=
generatedFunctionGraph
->
node
(
currentNodeId
);
81
82
LinkedList
<
NodeId
>
potentialSons
;
83
Idx
nbPotentialSons
= 0;
84
for
(
Idx
varPos
= 0;
varPos
<
generatedFunctionGraph
->
variablesSequence
().
size
();
varPos
++) {
85
const
DiscreteVariable
*
var
=
generatedFunctionGraph
->
variablesSequence
().
atPos
(
varPos
);
86
87
Idx
vsp
=
_varSeq_
.
pos
(
var
);
88
if
(
vsp
>
cvp
) {
89
const
Link
<
NodeId
>*
nicleIter
=
generatedFunctionGraph
->
varNodeListe
(
var
)->
list
();
90
while
(
nicleIter
) {
91
nbPotentialSons
++;
92
potentialSons
.
addLink
(
nicleIter
->
element
());
93
nicleIter
=
nicleIter
->
nextLink
();
94
}
95
}
96
}
97
98
for
(
Idx
modality
= 0;
modality
<
currentNode
->
nodeVar
()->
domainSize
();
modality
++) {
99
if
(!
potentialSons
.
list
()
100
|| (
double
)
std
::
rand
() / (
double
)RAND_MAX > (1.0 / (1.0 + 3.0 /
nbPotentialSons
))) {
101
if
(
_createLeaf_
(
currentNodeId
,
node2MinVar
)) {
102
generatedFunctionGraph
->
manager
()->
setSon
(
103
currentNodeId
,
104
modality
,
105
generatedFunctionGraph
->
manager
()->
addTerminalNode
((
double
)
std
::
rand
()
106
/ (
double
)RAND_MAX * 100));
107
}
else
{
108
Idx
sonVarPos
=
_generateVarPos_
(
node2MinVar
[
currentNodeId
] + 1,
109
_nbTotalVar_
-
node2MinVar
[
currentNodeId
] - 2);
110
generatedFunctionGraph
->
manager
()->
setSon
(
111
currentNodeId
,
112
modality
,
113
generatedFunctionGraph
->
manager
()->
addInternalNode
(
_varSeq_
.
atPos
(
sonVarPos
)));
114
filo
.
push_back
(
currentNode
->
son
(
modality
));
115
node2MinVar
.
insert
(
currentNode
->
son
(
modality
),
sonVarPos
);
116
}
117
}
else
{
118
Idx
sonPos
= (
Idx
)(((
double
)
std
::
rand
() / (
double
)RAND_MAX) *
nbPotentialSons
);
119
sonPos
=
sonPos
==
nbPotentialSons
?
nbPotentialSons
- 1 :
sonPos
;
120
Link
<
NodeId
>*
nicleIter
=
potentialSons
.
list
();
121
while
(
sonPos
) {
122
nicleIter
=
nicleIter
->
nextLink
();
123
sonPos
--;
124
}
125
generatedFunctionGraph
->
manager
()->
setSon
(
currentNodeId
,
modality
,
nicleIter
->
element
());
126
}
127
}
128
++
nbIter
;
129
}
130
131
generatedFunctionGraph
->
manager
()->
reduce
();
132
generatedFunctionGraph
->
manager
()->
clean
();
133
134
return
generatedFunctionGraph
;
135
}
136
137
bool
MultiDimFunctionGraphGenerator
::
_createLeaf_
(
NodeId
currentNodeId
,
138
HashTable
<
NodeId
,
Idx
>&
node2MinVar
) {
139
return
!(
140
currentNodeId
== 1
141
|| ((
double
)
std
::
rand
() / (
double
)RAND_MAX
142
< 0.9
143
+ 0.01 * (
float
(
_nbTotalVar_
-
node2MinVar
[
currentNodeId
]) /
float
(
_nbTotalVar_
))
144
&&
node2MinVar
[
currentNodeId
] <
_nbTotalVar_
- 1));
145
}
146
147
Idx
MultiDimFunctionGraphGenerator
::
_generateVarPos_
(
Idx
offset
,
Idx
span
) {
148
Idx
randOut
= 0;
149
150
if
(
span
!= 0) {
151
auto
generator
=
gum
::
getRandomGenerator
();
152
std
::
weibull_distribution
<
double
>
distribution
(
double
(
span
), 1.0);
153
randOut
= (
Idx
)(
distribution
(
generator
) *
span
/ 2);
154
if
(
randOut
>
span
)
randOut
=
span
;
155
}
156
157
return
offset
+
randOut
;
158
}
159
160
}
// namespace gum
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643