aGrUM  0.14.2
multiDimFunctionGraphGenerator.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
29 #include <cstdlib>
30 #include <random>
31 
34 
35 namespace gum {
36  // Constructor
38  Idx maxVar, Idx minVar, const Sequence< const DiscreteVariable* >& varSeq) :
39  __varSeq(varSeq) {
40  GUM_CONSTRUCTOR(MultiDimFunctionGraphGenerator);
41 
42  __nbTotalVar = __varSeq.size();
43  }
44 
45  // Destructor
47  GUM_DESTRUCTOR(MultiDimFunctionGraphGenerator);
48  }
49 
51  MultiDimFunctionGraph< double >* generatedFunctionGraph =
53 
55  __varSeq.beginSafe();
56  varIter != __varSeq.endSafe();
57  ++varIter) {
58  generatedFunctionGraph->add(**varIter);
59  }
60 
61  HashTable< NodeId, Idx > node2MinVar;
62  Idx nbIter = 0;
63 
64  std::vector< NodeId > filo;
65 
66  generatedFunctionGraph->manager()->setRootNode(
67  generatedFunctionGraph->manager()->addInternalNode(__varSeq.atPos(0)));
68  node2MinVar.insert(generatedFunctionGraph->root(), 0);
69  filo.push_back(generatedFunctionGraph->root());
70 
71  while (!filo.empty()) { //&& nbIter < 20 ){
72 
73  NodeId currentNodeId = filo.back();
74  filo.pop_back();
75  Idx cvp = node2MinVar[currentNodeId];
76  const InternalNode* currentNode =
77  generatedFunctionGraph->node(currentNodeId);
78 
79  LinkedList< NodeId > potentialSons;
80  Idx nbPotentialSons = 0;
81  for (Idx varPos = 0;
82  varPos < generatedFunctionGraph->variablesSequence().size();
83  varPos++) {
84  const DiscreteVariable* var =
85  generatedFunctionGraph->variablesSequence().atPos(varPos);
86 
87  Idx vsp = __varSeq.pos(var);
88  if (vsp > cvp) {
89  const Link< NodeId >* nicleIter =
90  generatedFunctionGraph->varNodeListe(var)->list();
91  while (nicleIter) {
92  nbPotentialSons++;
93  potentialSons.addLink(nicleIter->element());
94  nicleIter = nicleIter->nextLink();
95  }
96  }
97  }
98 
99  for (Idx modality = 0; modality < currentNode->nodeVar()->domainSize();
100  modality++) {
101  if (!potentialSons.list()
102  || (double)std::rand() / (double)RAND_MAX
103  > (1.0 / (1.0 + 3.0 / nbPotentialSons))) {
104  if (__createLeaf(currentNodeId, node2MinVar)) {
105  generatedFunctionGraph->manager()->setSon(
106  currentNodeId,
107  modality,
108  generatedFunctionGraph->manager()->addTerminalNode(
109  (double)std::rand() / (double)RAND_MAX * 100));
110  } else {
111  Idx sonVarPos =
112  __generateVarPos(node2MinVar[currentNodeId] + 1,
113  __nbTotalVar - node2MinVar[currentNodeId] - 2);
114  generatedFunctionGraph->manager()->setSon(
115  currentNodeId,
116  modality,
117  generatedFunctionGraph->manager()->addInternalNode(
118  __varSeq.atPos(sonVarPos)));
119  filo.push_back(currentNode->son(modality));
120  node2MinVar.insert(currentNode->son(modality), sonVarPos);
121  }
122  } else {
123  Idx sonPos =
124  (Idx)(((double)std::rand() / (double)RAND_MAX) * nbPotentialSons);
125  sonPos = sonPos == nbPotentialSons ? nbPotentialSons - 1 : sonPos;
126  Link< NodeId >* nicleIter = potentialSons.list();
127  while (sonPos) {
128  nicleIter = nicleIter->nextLink();
129  sonPos--;
130  }
131  generatedFunctionGraph->manager()->setSon(
132  currentNodeId, modality, nicleIter->element());
133  }
134  }
135  ++nbIter;
136  }
137 
138  generatedFunctionGraph->manager()->reduce();
139  generatedFunctionGraph->manager()->clean();
140 
141  return generatedFunctionGraph;
142  }
143 
145  NodeId currentNodeId, HashTable< NodeId, Idx >& node2MinVar) {
146  return !(currentNodeId == 1
147  || ((double)std::rand() / (double)RAND_MAX
148  < 0.9
149  + 0.01
150  * (float(__nbTotalVar - node2MinVar[currentNodeId])
151  / float(__nbTotalVar))
152  && node2MinVar[currentNodeId] < __nbTotalVar - 1));
153  }
154 
156  Idx randOut = 0;
157 
158  if (span != 0) {
159  auto generator = gum::getRandomGenerator();
160  std::weibull_distribution< double > distribution(double(span), 1.0);
161  randOut = (Idx)(distribution(generator) * span / 2);
162  if (randOut > span) randOut = span;
163  }
164 
165  return offset + randOut;
166  }
167 
168 } // namespace gum
Safe iterators for Sequence.
Definition: sequence.h:1203
void setSon(const NodeId &node, const Idx &modality, const NodeId &sonNode)
Sets nodes son for given modality to designated son node.
void clean()
Removes var without nodes in the diagram.
void setRootNode(const NodeId &root)
Sets root node of decision diagram.
const InternalNode * node(NodeId n) const
Returns internalNode structure associated to that nodeId.
Class implementing a function graph generator with template type double.
const DiscreteVariable * nodeVar() const
Returns the node variable.
The generic class for storing (ordered) sequences of objects.
Definition: sequence.h:1019
NodeId son(Idx modality) const
Returns the son at a given index.
NodeId addInternalNode(const DiscreteVariable *var)
Inserts a new non terminal node in graph.
MultiDimFunctionGraph< double > * generate()
Generates a MultiDimFunctionGraph.
Base class for discrete random variable.
Headers of gum::MultiDimFunctionGraphGenerator.
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
Idx __nbTotalVar
The total number of variables.
virtual Size domainSize() const =0
bool __createLeaf(NodeId currentNodeId, HashTable< NodeId, Idx > &node2MinVar)
Creates a leaf.
virtual void add(const DiscreteVariable &v)
Adds a new var to the variables of the multidimensional matrix.
Structure used to represent a node internal structure.
Definition: internalNode.h:100
const Sequence< const DiscreteVariable *> __varSeq
The variables.
const NodeId & root() const
Returns the id of the root node from the diagram.
const LinkedList< NodeId > * varNodeListe(const DiscreteVariable *var) const
Returns the list of node associated to given variable.
priority queues (in which an element cannot appear more than once)
virtual const Sequence< const DiscreteVariable *> & variablesSequence() const override
Returns a const ref to the sequence of DiscreteVariable*.
MultiDimFunctionGraphGenerator(Idx maxVar, Idx minVar, const Sequence< const DiscreteVariable * > &varSeq)
Default constructor.
Chain list allocated using the SmallObjectAllocator.
Definition: link.h:131
std::default_random_engine getRandomGenerator(unsigned int seed)
define a random_engine with correct seed
const Link< T > * list() const
Returns the first link in the chained list.
Definition: link_tpl.h:112
NodeId addTerminalNode(const GUM_SCALAR &value)
Adds a value to the MultiDimFunctionGraph.
Size Idx
Type for indexes.
Definition: types.h:50
MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy > * manager()
Returns a const reference to the manager of this diagram.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
virtual void reduce()=0
Ensures that every isomorphic subgraphs are merged together.
Idx __generateVarPos(Idx offset, Idx span)
Generate a variable position.
Size NodeId
Type for node ids.
Definition: graphElements.h:97
void addLink(const T &elem)
Adds a link.
Definition: link_tpl.h:133
static MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * getReducedAndOrderedInstance()
Returns a reduced and ordered instance.