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