aGrUM  0.14.2
multiDimFunctionGraphManager_tpl.h
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  ***************************************************************************/
28 #include <agrum/core/sequence.h>
31 
32 namespace gum {
33 
34  // Default constructor
35  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
39  GUM_CONSTRUCTOR(MultiDimFunctionGraphManager);
40  __functionGraph = mddg;
41  }
42 
43  // Destructor
44  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
47  GUM_DESTRUCTOR(MultiDimFunctionGraphManager);
48  }
49 
51  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
52  INLINE void
54  const NodeId& root) {
55  __functionGraph->__root = root;
56  }
57 
58  // Inserts a new non terminal node in graph.
59  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
62  InternalNode* newNodeStruct = new InternalNode(var);
63 
64  __functionGraph->__internalNodeMap.insert(nid, newNodeStruct);
65 
66  __functionGraph->__var2NodeIdMap[var]->addLink(nid);
67 
68  return nid;
69  }
70 
71  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
74  InternalNode* newNodeStruct = new InternalNode(var);
75  NodeId nid = __functionGraph->__model.addNode();
76  __functionGraph->__internalNodeMap.insert(nid, newNodeStruct);
77  __functionGraph->__var2NodeIdMap[var]->addLink(nid);
78 
79  return nid;
80  }
81 
82  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
85  InternalNode* newNodeStruct = new InternalNode(var, sons);
86  NodeId nid = __functionGraph->__model.addNode();
87  __functionGraph->__internalNodeMap.insert(nid, newNodeStruct);
88  __functionGraph->__var2NodeIdMap[var]->addLink(nid);
89  for (Idx i = 0; i < newNodeStruct->nbSons(); i++)
90  if (!__functionGraph->isTerminalNode(sons[i]))
91  __functionGraph->__internalNodeMap[sons[i]]->addParent(nid, i);
92 
93  return nid;
94  }
95 
96  // Adds a value to the MultiDimFunctionGraph.
97  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
99  addTerminalNode(const GUM_SCALAR& value) {
100  if (__functionGraph->existsTerminalNodeWithValue(value))
101  return __functionGraph->terminalNodeId(value);
102 
103  NodeId node = __functionGraph->__model.addNode();
104  __functionGraph->addTerminalNode(node, value);
105  return node;
106  }
107 
108  // Erases a node from the diagram.
109  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
111  NodeId eraseId, NodeId replacingId, bool updateParents) {
112  if (!__functionGraph->__model.exists(eraseId))
113  GUM_ERROR(NotFound, "Node : " << eraseId << " doesn't exists in the graph")
114 
115  if (__functionGraph->isTerminalNode(eraseId)) {
116  for (auto iterVar = __functionGraph->variablesSequence().begin();
117  iterVar != __functionGraph->variablesSequence().end();
118  ++iterVar) {
119  Link< NodeId >* nodeIter =
120  __functionGraph->__var2NodeIdMap[*iterVar]->list();
121  while (nodeIter != nullptr) {
122  for (Idx modality = 0; modality < (*iterVar)->domainSize(); ++modality)
123  if (__functionGraph->node(nodeIter->element())->son(modality)
124  == eraseId)
125  setSon(nodeIter->element(), modality, replacingId);
126 
127  nodeIter = nodeIter->nextLink();
128  }
129  }
130  __functionGraph->eraseTerminalNode(eraseId);
131 
132  } else {
133  InternalNode* eraseNode = __functionGraph->__internalNodeMap[eraseId];
134 
135  if (updateParents) {
136  Link< Parent >* picle = eraseNode->parents();
137  while (picle != nullptr) {
138  setSon(
139  picle->element().parentId, picle->element().modality, replacingId);
140  picle = picle->nextLink();
141  }
142  }
143 
144  __functionGraph
145  ->__var2NodeIdMap[__functionGraph->__internalNodeMap[eraseId]->nodeVar()]
146  ->searchAndRemoveLink(eraseId);
147 
148  delete __functionGraph->__internalNodeMap[eraseId];
149  __functionGraph->__internalNodeMap.erase(eraseId);
150  }
151 
152  __functionGraph->__model.eraseNode(eraseId);
153 
154  if (__functionGraph->__root == eraseId) __functionGraph->__root = replacingId;
155  }
156 
158  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
159  INLINE void
161  const NodeId& node, const Idx& modality, const NodeId& sonNode) {
162  // Ensuring that both nodes exists in the graph
163  if (!__functionGraph->__model.exists(node))
164  GUM_ERROR(NotFound, "Node : " << node << " doesn't exists in the graph")
165  if (!__functionGraph->__model.exists(sonNode))
166  GUM_ERROR(NotFound, "Node : " << sonNode << " doesn't exists in the graph")
167 
168  // Check if starting node is not terminal
169  if (__functionGraph->isTerminalNode(node))
171  "You cannot insert an arc from terminal node : " << node)
172 
173  // Check if associated modality is lower than node bound variable domain
174  // size
175  if (__functionGraph->isInternalNode(node)
176  && modality
177  > __functionGraph->__internalNodeMap[node]->nodeVar()->domainSize()
178  - 1)
179  GUM_ERROR(
181  "Modality "
182  << modality << "is higher than domain size "
183  << __functionGraph->__internalNodeMap[node]->nodeVar()->domainSize()
184  << "minus 1 of variable "
185  << __functionGraph->__internalNodeMap[node]->nodeVar()->name())
186 
187  // Check if variable order is respected
188  if (__functionGraph->isInternalNode(sonNode)
189  && __functionGraph->variablesSequence().pos(
190  __functionGraph->__internalNodeMap[node]->nodeVar())
191  >= __functionGraph->variablesSequence().pos(
192  __functionGraph->__internalNodeMap[sonNode]->nodeVar()))
193  GUM_ERROR(
195  "Variable " << __functionGraph->__internalNodeMap[node]->nodeVar()
196  << " is after variable "
197  << __functionGraph->__internalNodeMap[sonNode]->nodeVar()
198  << "in Function Graph order.")
199 
200  __functionGraph->__internalNodeMap[node]->setSon(modality, sonNode);
201  if (sonNode && !__functionGraph->isTerminalNode(sonNode))
202  __functionGraph->__internalNodeMap[sonNode]->addParent(node, modality);
203  }
204 
205  // Changes var position in variable sequence
206  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
207  void MultiDimFunctionGraphManager< GUM_SCALAR,
208  TerminalNodePolicy >::minimizeSize() {
209  // Ordering variables by number of nodes asssociated to them
213  __functionGraph->variablesSequence().beginSafe();
214  varIter != __functionGraph->variablesSequence().endSafe();
215  ++varIter) {
216  const Link< NodeId >* curElem =
217  __functionGraph->__var2NodeIdMap[*varIter]->list();
218  Idx nbElem = 0;
219  for (; curElem != nullptr; nbElem++, curElem = curElem->nextLink())
220  ;
221  varLvlSize.insert(*varIter, nbElem);
222  siftingSeq.insert(*varIter);
223  Idx pos = siftingSeq.pos(*varIter);
224  while (pos > 0 && varLvlSize[siftingSeq.atPos(pos - 1)] > nbElem) {
225  siftingSeq.swap(pos - 1, pos);
226  pos--;
227  }
228  }
229 
230  // Sifting var par var
232  siftingSeq.beginSafe();
233  sifIter != siftingSeq.endSafe();
234  ++sifIter) {
235  // Initialization
236  Idx currentPos = __functionGraph->variablesSequence().pos(*sifIter);
237  Idx bestSize = __functionGraph->realSize();
238  Idx bestPos = currentPos;
239 
240 
241  // Sifting towards upper places
242  while (currentPos > 0) {
243  moveTo(*sifIter, currentPos - 1);
244  currentPos = __functionGraph->variablesSequence().pos(*sifIter);
245  if (__functionGraph->realSize() < bestSize) {
246  bestPos = currentPos;
247  bestSize = __functionGraph->realSize();
248  }
249  }
250 
251  // Sifting towards lower places
252  while (currentPos < __functionGraph->variablesSequence().size() - 1) {
253  moveTo(*sifIter, currentPos + 1);
254  currentPos = __functionGraph->variablesSequence().pos(*sifIter);
255  if (__functionGraph->realSize() < bestSize) {
256  bestPos = currentPos;
257  bestSize = __functionGraph->realSize();
258  }
259  }
260 
261  moveTo(*sifIter, bestPos);
262  }
263  }
264 
265  // Changes var position in variable sequence
266  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
268  const DiscreteVariable* movedVar, Idx desiredPos) {
269  // First we determine the position of both variable
270  // We also determine which one precede the other
271  if (__functionGraph->variablesSequence().pos(movedVar) > desiredPos)
272  for (Idx currentPos = __functionGraph->variablesSequence().pos(movedVar);
273  currentPos != desiredPos;
274  currentPos--) {
275  const DiscreteVariable* preVar =
276  __functionGraph->variablesSequence().atPos(currentPos - 1);
277  if (__functionGraph->__var2NodeIdMap[preVar]->list()
278  && __functionGraph->__var2NodeIdMap[movedVar]->list())
279  __adjacentSwap(preVar, movedVar);
280  __functionGraph->_invert(currentPos - 1, currentPos);
281  }
282  else
283  for (Idx currentPos = __functionGraph->variablesSequence().pos(movedVar);
284  currentPos != desiredPos;
285  currentPos++) {
286  const DiscreteVariable* suiVar =
287  __functionGraph->variablesSequence().atPos(currentPos + 1);
288  if (__functionGraph->__var2NodeIdMap[suiVar]->list()
289  && __functionGraph->__var2NodeIdMap[movedVar]->list())
290  __adjacentSwap(movedVar, suiVar);
291  __functionGraph->_invert(currentPos, currentPos + 1);
292  }
293  }
294 
295  // Swap two adjacent variable.
296  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
299  LinkedList< NodeId >* oldxNodes = __functionGraph->__var2NodeIdMap[x];
300  __functionGraph->__var2NodeIdMap[x] = new LinkedList< NodeId >();
301  LinkedList< NodeId >* oldyNodes = __functionGraph->__var2NodeIdMap[y];
302  __functionGraph->__var2NodeIdMap[y] = new LinkedList< NodeId >();
303 
304 
305  InternalNode* currentOldXNode = nullptr;
306  NodeId* currentNewXNodeSons = nullptr;
307  Idx indx = 0;
308 
309  NodeId* currentNewYNodeSons = nullptr;
310  NodeId currentNewYNodeId = 0;
311  Idx indy = 0;
312 
313  while (oldxNodes->list()) {
314  // Recuperating a node associated to variables x
315  currentOldXNode =
316  __functionGraph->__internalNodeMap[oldxNodes->list()->element()];
317 
318  // Creating a new node associated to variable y
319  currentNewYNodeSons = InternalNode::allocateNodeSons(y);
320 
321  // Now the graph needs to be remap by inserting nodes bound to x
322  // for each values assumed by y
323  for (indy = 0; indy < y->domainSize(); ++indy) {
324  // Creating a new node bound to x that will be the son of the node
325  // tied to y for the current value assumed by y
326  currentNewXNodeSons = InternalNode::allocateNodeSons(x);
327 
328  // Iterating on the different values taht x can assumed to do the remap
329  for (indx = 0; indx < x->domainSize(); ++indx) {
330  currentNewXNodeSons[indx] = currentOldXNode->son(indx);
331  if (!__functionGraph->isTerminalNode(currentOldXNode->son(indx))
332  && __functionGraph->node(currentOldXNode->son(indx))->nodeVar() == y)
333  currentNewXNodeSons[indx] =
334  __functionGraph->node(currentOldXNode->son(indx))->son(indy);
335  }
336 
337  // Inserting the new node bound to x
338  currentNewYNodeSons[indy] = _nodeRedundancyCheck(x, currentNewXNodeSons);
339  }
340 
341  // Replacing old node x by new node y
342  currentNewYNodeId = currentNewYNodeSons[0];
343  if (__isRedundant(y, currentNewYNodeSons)) {
344  _migrateNode(oldxNodes->list()->element(), currentNewYNodeId);
345  SOA_DEALLOCATE(currentNewYNodeSons, y->domainSize() * sizeof(NodeId));
346  } else {
347  currentNewYNodeId = __checkIsomorphism(y, currentNewYNodeSons);
348  if (currentNewYNodeId != 0) {
349  _migrateNode(oldxNodes->list()->element(), currentNewYNodeId);
350  SOA_DEALLOCATE(currentNewYNodeSons, y->domainSize() * sizeof(NodeId));
351  } else {
352  // Updating the sons (they must not consider old x as their parent)
353  for (Idx i = 0; i < currentOldXNode->nodeVar()->domainSize(); ++i) {
354  if (__functionGraph->__internalNodeMap.exists(
355  currentOldXNode->son(i))) {
356  __functionGraph->__internalNodeMap[currentOldXNode->son(i)]
357  ->removeParent(oldxNodes->list()->element(), i);
358  }
359  }
360  // Reaffecting old node x internal attributes to correct new one
361  currentOldXNode->setNode(y, currentNewYNodeSons);
362  // Updating new sons (they must consider the node as a parent)
363  for (Idx i = 0; i < currentOldXNode->nodeVar()->domainSize(); ++i) {
364  if (__functionGraph->__internalNodeMap.exists(
365  currentNewYNodeSons[i])) {
366  __functionGraph->__internalNodeMap[currentNewYNodeSons[i]]
367  ->addParent(oldxNodes->list()->element(), i);
368  }
369  }
370 
371  __functionGraph->__var2NodeIdMap[y]->addLink(
372  oldxNodes->list()->element());
373  }
374  }
375 
376  oldxNodes->searchAndRemoveLink(oldxNodes->list()->element());
377  }
378  delete oldxNodes;
379 
380  while (oldyNodes->list()) {
381  NodeId curId = oldyNodes->list()->element();
382  if (__functionGraph->__internalNodeMap[curId]->parents() == nullptr) {
383  for (Idx i = 0;
384  i
385  < __functionGraph->__internalNodeMap[curId]->nodeVar()->domainSize();
386  ++i)
387  if (__functionGraph->__internalNodeMap.exists(
388  __functionGraph->__internalNodeMap[curId]->son(i)))
389  __functionGraph
390  ->__internalNodeMap[__functionGraph->__internalNodeMap[curId]->son(
391  i)]
392  ->removeParent(curId, i);
393  delete __functionGraph->__internalNodeMap[curId];
394  __functionGraph->__internalNodeMap.erase(curId);
395  __functionGraph->__model.eraseNode(curId);
396  } else {
397  __functionGraph->__var2NodeIdMap[y]->addLink(curId);
398  }
399  oldyNodes->searchAndRemoveLink(curId);
400  }
401  delete oldyNodes;
402  }
403 
404  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
405  INLINE void
407  const NodeId& origin, const NodeId& destination) {
408  InternalNode* org = __functionGraph->__internalNodeMap[origin];
409  // Upating parents after the change
410  Link< Parent >* picle = org->parents();
411  while (picle != nullptr) {
412  setSon(picle->element().parentId, picle->element().modality, destination);
413  picle = picle->nextLink();
414  }
415 
416  // Updating sons after the change
417  for (Idx i = 0; i < org->nbSons(); ++i)
418  if (__functionGraph->__internalNodeMap.exists(org->son(i)))
419  __functionGraph->__internalNodeMap[org->son(i)]->removeParent(origin, i);
420 
421  delete org;
422  __functionGraph->__internalNodeMap.erase(origin);
423  __functionGraph->__model.eraseNode(origin);
424 
425  if (__functionGraph->root() == origin) this->setRootNode(destination);
426  }
427 
428  // Checks if a similar node does not already exists in the graph or
429  // if it has the same child for every variable value.
430  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
433  NodeId newNode = sonsIds[0];
434 
435  if (__isRedundant(var, sonsIds)) {
436  SOA_DEALLOCATE(sonsIds, sizeof(NodeId) * var->domainSize());
437  } else {
438  newNode = __checkIsomorphism(var, sonsIds);
439  if (newNode == 0) {
440  newNode = _addInternalNode(var, sonsIds);
441  } else {
442  SOA_DEALLOCATE(sonsIds, sizeof(NodeId) * var->domainSize());
443  }
444  }
445 
446  return newNode;
447  }
448 
449  // Checks if a similar node does not already exists in the graph.
450  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
453  const InternalNode* nody = nullptr;
454  Idx i = 0;
455 
456  // Check abscence of identical node
457  Link< NodeId >* currentElem = __functionGraph->__var2NodeIdMap[var]->list();
458  while (currentElem != nullptr) {
459  nody = __functionGraph->__internalNodeMap[currentElem->element()];
460 
461  // Check on the other sons
462  i = 0;
463  while (i < var->domainSize() && sons[i] == nody->son(i))
464  ++i;
465  if (i == var->domainSize()) return currentElem->element();
466 
467  currentElem = currentElem->nextLink();
468  }
469  return 0;
470  }
471 
472  // Checks if node has the same child for every variable value
473  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
474  INLINE bool
476  const DiscreteVariable* var, NodeId* sons) {
477  for (Idx m = 1; m < var->domainSize(); m++)
478  if (sons[m] != sons[0]) return false;
479  return true;
480  }
481 
482  // Ensures that every isomorphic subgraphs are merged together.
483  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
484  INLINE void
486  Link< NodeId >* currentNodeId = nullptr;
487  Link< NodeId >* nextNodeId = nullptr;
488  InternalNode* currentNode = nullptr;
489  bool theSame = true;
490  Idx currentInd;
491 
492  for (SequenceIterator< const DiscreteVariable* > varIter =
493  __functionGraph->variablesSequence().rbegin();
494  varIter != __functionGraph->variablesSequence().rend();
495  --varIter) {
496  currentNodeId = __functionGraph->__var2NodeIdMap[*varIter]->list();
497 
498  while (currentNodeId != nullptr) {
499  nextNodeId = currentNodeId->nextLink();
500  currentNode = __functionGraph->__internalNodeMap[currentNodeId->element()];
501 
502  // First isomorphism to handle is the one where all node children are
503  // the same
504  theSame = true;
505  for (currentInd = 1; currentInd < (*varIter)->domainSize(); currentInd++) {
506  if (currentNode->son(currentInd) != currentNode->son(0)) {
507  theSame = false;
508  break;
509  }
510  }
511 
512  if (theSame == true) {
513  _migrateNode(currentNodeId->element(), currentNode->son(0));
514  __functionGraph->__var2NodeIdMap[*varIter]->searchAndRemoveLink(
515  currentNodeId->element());
516  currentNodeId = nextNodeId;
517  continue;
518  }
519 
520  // Second isomorphism to handle is the one where two nodes have same
521  // variable and same children
522  if (nextNodeId) {
523  Link< NodeId >* anotherNodeId = currentNodeId->nextLink();
524  InternalNode* anotherNode = nullptr;
525  Idx modality = 0;
526  while (anotherNodeId->nextLink() != nullptr) {
527  nextNodeId = anotherNodeId->nextLink();
528  anotherNode =
529  __functionGraph->__internalNodeMap[anotherNodeId->element()];
530 
531  // Check on the other sons
532  for (modality = 0; modality < (*varIter)->domainSize(); ++modality) {
533  if (anotherNode->son(modality) != currentNode->son(modality)) break;
534  if (modality == (*varIter)->domainSize() - 1) {
535  _migrateNode(anotherNodeId->element(), currentNodeId->element());
536  __functionGraph->__var2NodeIdMap[*varIter]->searchAndRemoveLink(
537  anotherNodeId->element());
538  }
539  }
540 
541  anotherNodeId = nextNodeId;
542  }
543  }
544  currentNodeId = currentNodeId->nextLink();
545  }
546  }
547  }
548 
549  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
550  INLINE void
553  __functionGraph->variablesSequence());
554  for (SequenceIterator< const DiscreteVariable* > varIter = oldSequence.begin();
555  varIter != oldSequence.end();
556  ++varIter)
557  if (!__functionGraph->varNodeListe(*varIter)->list())
558  __functionGraph->erase(**varIter);
559  }
560 
561  // ==========================================================================
562  // MultiDimFunctionGraphTreeManager
563  // ==========================================================================
564 
565  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
569  MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >(master) {
570  GUM_CONSTRUCTOR(MultiDimFunctionGraphTreeManager);
571  }
572 
573  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
576  GUM_DESTRUCTOR(MultiDimFunctionGraphTreeManager);
577  }
578 
579  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
582  return this->_addInternalNode(var, sons);
583  }
584 
585  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
586  void
588  }
589 
590  // ===========================================================================
591  // MultiDimFunctionGraphROManager
592  // ===========================================================================
593 
594  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
598  MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >(master) {
599  GUM_CONSTRUCTOR(MultiDimFunctionGraphROManager);
600  }
601 
602  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
605  GUM_DESTRUCTOR(MultiDimFunctionGraphROManager);
606  }
607 
608  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
611  return this->_nodeRedundancyCheck(var, sons);
612  }
613 
614  template < typename GUM_SCALAR, template < class > class TerminalNodePolicy >
616  this->_reduce();
617  }
618 
619 } // namespace gum
virtual void reduce()
Ensures that every isomorphic subgraphs are merged together.
Headers of MultiDimFunctionGraphManager.
Safe iterators for Sequence.
Definition: sequence.h:1203
Idx pos(const Key &key) const
Returns the position of the object passed in argument (if it exists).
Definition: sequence_tpl.h:515
void setSon(const NodeId &node, const Idx &modality, const NodeId &sonNode)
Sets nodes son for given modality to designated son node.
NodeId parentId
Definition: internalNode.h:49
void clean()
Removes var without nodes in the diagram.
void __adjacentSwap(const DiscreteVariable *x, const DiscreteVariable *y)
Swap two adjacent variable.
void setRootNode(const NodeId &root)
Sets root node of decision diagram.
const iterator_safe & endSafe() const noexcept
Returns the safe end iterator.
Definition: sequence_tpl.h:631
Header file of gum::Sequence, a class for storing (ordered) sequences of objects. ...
Idx nbSons() const
Returns the number of sons.
The generic class for storing (ordered) sequences of objects.
Definition: sequence.h:1019
static NodeId * allocateNodeSons(const DiscreteVariable *v)
Allocates a table of nodeid of the size given in parameter.
#define SOA_DEALLOCATE(x, y)
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.
Link< Parent > * parents()
Returns the list of parents.
Base class for discrete random variable.
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
void moveTo(const DiscreteVariable *x, Idx desiredPos)
Changes var position in variable sequence.
The class for generic Hash Tables.
Definition: hashTable.h:676
void searchAndRemoveLink(const T &elem)
Removes a element from the list.
Definition: link_tpl.h:139
void eraseNode(NodeId id, NodeId replacingId=0, bool updateParents=true)
Erases a node from the diagram.
iterator_safe beginSafe() const
Returns a safe begin iterator.
Definition: sequence_tpl.h:624
virtual Size domainSize() const =0
virtual NodeId addInternalNode(const DiscreteVariable *var, NodeId *sons)
Inserts a new non terminal node in graph.
Class implementingting a function graph manager.
void _migrateNode(const NodeId &x, const NodeId &y)
Remaps all arcs going to ou going from the first given node to the second node, then delete first nod...
MultiDimFunctionGraphManager(MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *master)
Default constructor.
virtual void reduce()
Ensures that every isomorphic subgraphs are merged together.
Structure used to represent a node internal structure.
Definition: internalNode.h:100
Class implementingting a function graph.
void _reduce()
Ensures that every isomorphic subgraphs are merged together.
MultiDimFunctionGraphROManager(MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *master)
NodeId nextNodeId()
Returns the next value of an unique counter for PRM&#39;s node id.
Definition: utils_prm.cpp:63
MultiDimFunctionGraphTreeManager(MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *master)
Class constructor.
void erase(const Key &k)
Remove an element from the sequence.
Definition: sequence_tpl.h:450
Chain list allocated using the SmallObjectAllocator.
Definition: link.h:131
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
bool __isRedundant(const DiscreteVariable *var, NodeId *sons)
Checks if node has the same child for every variable value.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
NodeId _nodeRedundancyCheck(const DiscreteVariable *var, NodeId *sonsMap)
Check for redundancy.
NodeId _addInternalNode(const DiscreteVariable *var, NodeId *sons)
Adds an internal node.
virtual ~MultiDimFunctionGraphManager()
Class destructor.
Size NodeId
Type for node ids.
Definition: graphElements.h:97
void addLink(const T &elem)
Adds a link.
Definition: link_tpl.h:133
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
NodeId __checkIsomorphism(const DiscreteVariable *var, NodeId *sons)
Checks if a similar node does not already exists in the graph.
const Key & atPos(Idx i) const
Returns the object at the pos i.
Definition: sequence_tpl.h:497
virtual NodeId addInternalNode(const DiscreteVariable *var, NodeId *sons)
Inserts a new non terminal node in graph.
void insert(const Key &k)
Insert an element at the end of the sequence.
Definition: sequence_tpl.h:405