aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy > Class Template Referenceabstract

Class implementingting a function graph manager. More...

#include <multiDimFunctionGraphManager.h>

Inheritance diagram for gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >:
Collaboration diagram for gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >:

Public Member Functions

void clean ()
 Removes var without nodes in the diagram.

Private Attributes

MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _functionGraph_
 The multidimdecisiongraph supposed to be edited.

Constructors / Destructors

MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy > * MultiDimFunctionGraph ()
 This friend methods from is the only way to get an instance of a manager.
 MultiDimFunctionGraphManager (MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *master)
 Default constructor.
virtual ~MultiDimFunctionGraphManager ()
 Class destructor.

Nodes manipulation methods.

NodeId addInternalNode_ (const DiscreteVariable *var, NodeId *sons)
 Adds an internal node.
void setRootNode (const NodeId &root)
 Sets root node of decision diagram.
NodeId addInternalNode (const DiscreteVariable *var)
 Inserts a new non terminal node in graph.
virtual NodeId addInternalNode (const DiscreteVariable *var, NodeId *sons)=0
 Inserts a new non terminal node in graph.
NodeId addInternalNode (const DiscreteVariable *var, NodeId nid)
 Inserts a new non terminal node in graph.
NodeId addTerminalNode (const GUM_SCALAR &value)
 Adds a value to the MultiDimFunctionGraph.
void eraseNode (NodeId id, NodeId replacingId=0, bool updateParents=true)
 Erases a node from the diagram.

Manipulation methods.

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 node.
void setSon (const NodeId &node, const Idx &modality, const NodeId &sonNode)
 Sets nodes son for given modality to designated son node.
void minimizeSize ()
 Performs a sifting in search of a(local) minimal size.
void moveTo (const DiscreteVariable *x, Idx desiredPos)
 Changes var position in variable sequence.
void _adjacentSwap_ (const DiscreteVariable *x, const DiscreteVariable *y)
 Swap two adjacent variable.

Redundancy methods.

NodeId nodeRedundancyCheck_ (const DiscreteVariable *var, NodeId *sonsMap)
 Check for redundancy.
void reduce_ ()
 Ensures that every isomorphic subgraphs are merged together.
virtual void reduce ()=0
 Ensures that every isomorphic subgraphs are merged together.
NodeId _checkIsomorphism_ (const DiscreteVariable *var, NodeId *sons)
 Checks if a similar node does not already exists in the graph.
bool _isRedundant_ (const DiscreteVariable *var, NodeId *sons)
 Checks if node has the same child for every variable value.

Detailed Description

template<typename GUM_SCALAR, template< typename > class TerminalNodePolicy>
class gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >

Class implementingting a function graph manager.

Warning
Doxygen does not like spanning command on multiple line, so we could not configure it with the correct include directive. Use the following code snippet to include this file.

This class provides methods to edit a Function Graph. Any modification on a MultiDimFunctionGraph graph must be done via this class.

This class is a singleton and its unique instance ca be accessed using the MultiDimFunctionGraph::getManager() method.

To do so :

// You can also use getTreeInstance()
auto * func_graph =
auto manager = dg->manager();
static MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * getReducedAndOrderedInstance()
Returns a reduced and ordered instance.
Template Parameters
GUM_SCALARThe type of scalars stored in the multidimensional table.
TerminalNodePolicyThe terminal node policy to use.

Definition at line 97 of file multiDimFunctionGraphManager.h.

Constructor & Destructor Documentation

◆ MultiDimFunctionGraphManager()

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
INLINE gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::MultiDimFunctionGraphManager ( MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * master)
explicitprotected

Default constructor.

You have to call MultiDimFunctionGraph::getManager() to get the instance of MultiDimFunctionGraphManager bound to your function graph.

Definition at line 61 of file multiDimFunctionGraphManager_tpl.h.

62 {
65 }
Class implementingting a function graph manager.
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _functionGraph_
The multidimdecisiongraph supposed to be edited.
MultiDimFunctionGraphManager(MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *master)
Default constructor.

References MultiDimFunctionGraphManager(), and _functionGraph_.

Referenced by MultiDimFunctionGraphManager(), gum::MultiDimFunctionGraphROManager< GUM_SCALAR, TerminalNodePolicy >::MultiDimFunctionGraphROManager(), gum::MultiDimFunctionGraphTreeManager< GUM_SCALAR, TerminalNodePolicy >::MultiDimFunctionGraphTreeManager(), ~MultiDimFunctionGraphManager(), and minimizeSize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ~MultiDimFunctionGraphManager()

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
INLINE gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::~MultiDimFunctionGraphManager ( )
virtual

Class destructor.

Definition at line 70 of file multiDimFunctionGraphManager_tpl.h.

References MultiDimFunctionGraphManager(), and ~MultiDimFunctionGraphManager().

Referenced by ~MultiDimFunctionGraphManager().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Function Documentation

◆ _adjacentSwap_()

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
void gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::_adjacentSwap_ ( const DiscreteVariable * x,
const DiscreteVariable * y )
private

Swap two adjacent variable.

Order is important here. X must precede Y before the swap (at the end Y will then precede X). Not respecting this constraint leads to unattended behaviour.

Parameters
xThe first variable to swap.
yThe second variable to swap.

Definition at line 311 of file multiDimFunctionGraphManager_tpl.h.

313 {
314 LinkedList< NodeId >* oldxNodes = _functionGraph_->_var2NodeIdMap_[x];
315 _functionGraph_->_var2NodeIdMap_[x] = new LinkedList< NodeId >();
316 LinkedList< NodeId >* oldyNodes = _functionGraph_->_var2NodeIdMap_[y];
317 _functionGraph_->_var2NodeIdMap_[y] = new LinkedList< NodeId >();
318
319
320 InternalNode* currentOldXNode = nullptr;
321 NodeId* currentNewXNodeSons = nullptr;
322 Idx indx = 0;
323
324 NodeId* currentNewYNodeSons = nullptr;
326 Idx indy = 0;
327
328 while (oldxNodes->list()) {
329 // Recuperating a node associated to variables x
330 currentOldXNode = _functionGraph_->_internalNodeMap_[oldxNodes->list()->element()];
331
332 // Creating a new node associated to variable y
334
335 // Now the graph needs to be remap by inserting nodes bound to x
336 // for each values assumed by y
337 for (indy = 0; indy < y->domainSize(); ++indy) {
338 // Creating a new node bound to x that will be the son of the node
339 // tied to y for the current value assumed by y
341
342 // Iterating on the different values taht x can assumed to do the remap
343 for (indx = 0; indx < x->domainSize(); ++indx) {
345 if (!_functionGraph_->isTerminalNode(currentOldXNode->son(indx))
346 && _functionGraph_->node(currentOldXNode->son(indx))->nodeVar() == y)
348 = _functionGraph_->node(currentOldXNode->son(indx))->son(indy);
349 }
350
351 // Inserting the new node bound to x
353 }
354
355 // Replacing old node x by new node y
358 migrateNode_(oldxNodes->list()->element(), currentNewYNodeId);
359 SOA_DEALLOCATE(currentNewYNodeSons, y->domainSize() * sizeof(NodeId));
360 } else {
362 if (currentNewYNodeId != 0) {
363 migrateNode_(oldxNodes->list()->element(), currentNewYNodeId);
364 SOA_DEALLOCATE(currentNewYNodeSons, y->domainSize() * sizeof(NodeId));
365 } else {
366 // Updating the sons (they must not consider old x as their parent)
367 for (Idx i = 0; i < currentOldXNode->nodeVar()->domainSize(); ++i) {
368 if (_functionGraph_->_internalNodeMap_.exists(currentOldXNode->son(i))) {
369 _functionGraph_->_internalNodeMap_[currentOldXNode->son(i)]->removeParent(
370 oldxNodes->list()->element(),
371 i);
372 }
373 }
374 // Reaffecting old node x internal attributes to correct new one
376 // Updating new sons (they must consider the node as a parent)
377 for (Idx i = 0; i < currentOldXNode->nodeVar()->domainSize(); ++i) {
378 if (_functionGraph_->_internalNodeMap_.exists(currentNewYNodeSons[i])) {
379 _functionGraph_->_internalNodeMap_[currentNewYNodeSons[i]]->addParent(
380 oldxNodes->list()->element(),
381 i);
382 }
383 }
384
385 _functionGraph_->_var2NodeIdMap_[y]->addLink(oldxNodes->list()->element());
386 }
387 }
388
389 oldxNodes->searchAndRemoveLink(oldxNodes->list()->element());
390 }
391 delete oldxNodes;
392
393 while (oldyNodes->list()) {
394 NodeId curId = oldyNodes->list()->element();
395 if (_functionGraph_->_internalNodeMap_[curId]->parents() == nullptr) {
396 for (Idx i = 0; i < _functionGraph_->_internalNodeMap_[curId]->nodeVar()->domainSize(); ++i)
397 if (_functionGraph_->_internalNodeMap_.exists(
398 _functionGraph_->_internalNodeMap_[curId]->son(i)))
399 _functionGraph_->_internalNodeMap_[_functionGraph_->_internalNodeMap_[curId]->son(i)]
400 ->removeParent(curId, i);
401 delete _functionGraph_->_internalNodeMap_[curId];
402 _functionGraph_->_internalNodeMap_.erase(curId);
403 _functionGraph_->_model_.eraseNode(curId);
404 } else {
405 _functionGraph_->_var2NodeIdMap_[y]->addLink(curId);
406 }
407 oldyNodes->searchAndRemoveLink(curId);
408 }
409 delete oldyNodes;
410 }
static NodeId * allocateNodeSons(const DiscreteVariable *v)
Allocates a table of nodeid of the size given in parameter.
bool _isRedundant_(const DiscreteVariable *var, NodeId *sons)
Checks if node has the same child for every variable value.
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...
NodeId _checkIsomorphism_(const DiscreteVariable *var, NodeId *sons)
Checks if a similar node does not already exists in the graph.
NodeId nodeRedundancyCheck_(const DiscreteVariable *var, NodeId *sonsMap)
Check for redundancy.
#define SOA_DEALLOCATE(x, y)

References _adjacentSwap_(), and _functionGraph_.

Referenced by _adjacentSwap_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _checkIsomorphism_()

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
INLINE NodeId gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::_checkIsomorphism_ ( const DiscreteVariable * var,
NodeId * sons )
private

Checks if a similar node does not already exists in the graph.

Tow nodes are similar if for every value assumed by the associated variable, these two nodes have the same children.

Warning
This will not free sons.
Parameters
varThe node to check for.
sonsThe node sons.
Returns
Returns the node id if found, 0 otherwhise.

Definition at line 461 of file multiDimFunctionGraphManager_tpl.h.

463 {
464 const InternalNode* nody = nullptr;
465 Idx i = 0;
466
467 // Check abscence of identical node
468 Link< NodeId >* currentElem = _functionGraph_->_var2NodeIdMap_[var]->list();
469 while (currentElem != nullptr) {
470 nody = _functionGraph_->_internalNodeMap_[currentElem->element()];
471
472 // Check on the other sons
473 i = 0;
474 while (i < var->domainSize() && sons[i] == nody->son(i))
475 ++i;
476 if (i == var->domainSize()) return currentElem->element();
477
478 currentElem = currentElem->nextLink();
479 }
480 return 0;
481 }

References _checkIsomorphism_(), _functionGraph_, gum::DiscreteVariable::domainSize(), gum::Link< T >::element(), gum::Link< T >::nextLink(), and gum::InternalNode::son().

Referenced by _checkIsomorphism_(), and nodeRedundancyCheck_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _isRedundant_()

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
INLINE bool gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::_isRedundant_ ( const DiscreteVariable * var,
NodeId * sons )
private

Checks if node has the same child for every variable value.

Warning
WON'T deallocate sons
Parameters
varThe node to check for.
sonsThe node sons.
Returns
Returns true if the node is redundant.

Definition at line 485 of file multiDimFunctionGraphManager_tpl.h.

487 {
488 for (Idx m = 1; m < var->domainSize(); m++)
489 if (sons[m] != sons[0]) return false;
490 return true;
491 }

References _isRedundant_(), and gum::DiscreteVariable::domainSize().

Referenced by _isRedundant_(), and nodeRedundancyCheck_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ addInternalNode() [1/3]

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
INLINE NodeId gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::addInternalNode ( const DiscreteVariable * var)

Inserts a new non terminal node in graph.

NodeId of this node is generated automatically.

Parameters
varAssociated variable
Returns
The id of the added non terminal node.

Definition at line 96 of file multiDimFunctionGraphManager_tpl.h.

97 {
99 NodeId nid = _functionGraph_->_model_.addNode();
100 _functionGraph_->_internalNodeMap_.insert(nid, newNodeStruct);
101 _functionGraph_->_var2NodeIdMap_[var]->addLink(nid);
102
103 return nid;
104 }

References _functionGraph_.

Referenced by gum::AdaptiveRMaxPlaner::_visitLearner_(), and gum::MultiDimFunctionGraphGenerator::generate().

Here is the caller graph for this function:

◆ addInternalNode() [2/3]

template<typename GUM_SCALAR, template< typename > class TerminalNodePolicy>
virtual NodeId gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::addInternalNode ( const DiscreteVariable * var,
NodeId * sons )
pure virtual

Inserts a new non terminal node in graph.

NodeId of this node is generated automatically.

Parameters
varThe associated variable.
sonsA table of size var->domainSize() containing nodeid of sons nodes.
Returns
Returns the id of the added non terminal node.
Exceptions
OperationNotAllowedRaised if MultiDimFunctionGraph has no variable yet.

Implemented in gum::MultiDimFunctionGraphROManager< GUM_SCALAR, TerminalNodePolicy >, and gum::MultiDimFunctionGraphTreeManager< GUM_SCALAR, TerminalNodePolicy >.

◆ addInternalNode() [3/3]

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
INLINE NodeId gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::addInternalNode ( const DiscreteVariable * var,
NodeId nid )

Inserts a new non terminal node in graph.

NodeId of this node is generated automatically.

Parameters
varThe ssociated variable.
nidThe desired id for that node.
Returns
Returns the id of the added non terminal node.
Exceptions
OperationNotAllowedRaised if MultiDimFunctionGraph has no variable yet.

Definition at line 83 of file multiDimFunctionGraphManager_tpl.h.

85 {
87
88 _functionGraph_->_internalNodeMap_.insert(nid, newNodeStruct);
89
90 _functionGraph_->_var2NodeIdMap_[var]->addLink(nid);
91
92 return nid;
93 }

References _functionGraph_.

◆ addInternalNode_()

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
INLINE NodeId gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::addInternalNode_ ( const DiscreteVariable * var,
NodeId * sons )
protected

Adds an internal node.

Parameters
varThe node to add.
sonsThe node sons.
Returns
Returns the added node id.

Definition at line 107 of file multiDimFunctionGraphManager_tpl.h.

109 {
111 NodeId nid = _functionGraph_->_model_.addNode();
112 _functionGraph_->_internalNodeMap_.insert(nid, newNodeStruct);
113 _functionGraph_->_var2NodeIdMap_[var]->addLink(nid);
114 for (Idx i = 0; i < newNodeStruct->nbSons(); i++)
115 if (!_functionGraph_->isTerminalNode(sons[i]))
116 _functionGraph_->_internalNodeMap_[sons[i]]->addParent(nid, i);
117
118 return nid;
119 }

References _functionGraph_, and gum::InternalNode::nbSons().

Referenced by gum::MultiDimFunctionGraphTreeManager< GUM_SCALAR, TerminalNodePolicy >::addInternalNode(), and nodeRedundancyCheck_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ addTerminalNode()

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
INLINE NodeId gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::addTerminalNode ( const GUM_SCALAR & value)

Adds a value to the MultiDimFunctionGraph.

This will create a terminal node, which of id is returned. If a terminal node with such value already exists, its id will be return instead.

Parameters
valueThe value added by copy.
Returns
Returns he id of the terminal node hence created.

Definition at line 123 of file multiDimFunctionGraphManager_tpl.h.

124 {
125 if (_functionGraph_->existsTerminalNodeWithValue(value))
126 return _functionGraph_->terminalNodeId(value);
127
128 NodeId node = _functionGraph_->_model_.addNode();
129 _functionGraph_->addTerminalNode(node, value);
130 return node;
131 }

References _functionGraph_.

Referenced by gum::AdaptiveRMaxPlaner::_visitLearner_(), and gum::MultiDimFunctionGraphGenerator::generate().

Here is the caller graph for this function:

◆ clean()

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
INLINE void gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::clean ( )

Removes var without nodes in the diagram.

Definition at line 558 of file multiDimFunctionGraphManager_tpl.h.

558 {
561 varIter != oldSequence.end();
562 ++varIter)
563 if (!_functionGraph_->varNodeListe(*varIter)->list()) _functionGraph_->erase(**varIter);
564 }

References _functionGraph_, gum::SequenceImplementation< Key, Gen >::begin(), clean(), and gum::SequenceImplementation< Key, Gen >::end().

Referenced by gum::AdaptiveRMaxPlaner::_makeRMaxFunctionGraphs_(), clean(), and gum::MultiDimFunctionGraphGenerator::generate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ eraseNode()

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
void gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::eraseNode ( NodeId id,
NodeId replacingId = 0,
bool updateParents = true )

Erases a node from the diagram.

Parameters
idThe id of the variable to erase.
replacingIdOffers the possibility to reroute any parent to the given node.
updateParentsIndicates if such remapping has to be done.
Exceptions
NotFoundRaised if node isn't in diagram.

Definition at line 135 of file multiDimFunctionGraphManager_tpl.h.

138 {
139 if (!_functionGraph_->_model_.exists(eraseId))
140 GUM_ERROR(NotFound, "Node : " << eraseId << " doesn't exists in the graph")
141
143 for (auto iterVar = _functionGraph_->variablesSequence().begin();
144 iterVar != _functionGraph_->variablesSequence().end();
145 ++iterVar) {
146 Link< NodeId >* nodeIter = _functionGraph_->_var2NodeIdMap_[*iterVar]->list();
147 while (nodeIter != nullptr) {
148 for (Idx modality = 0; modality < (*iterVar)->domainSize(); ++modality)
149 if (_functionGraph_->node(nodeIter->element())->son(modality) == eraseId)
150 setSon(nodeIter->element(), modality, replacingId);
151
152 nodeIter = nodeIter->nextLink();
153 }
154 }
155 _functionGraph_->eraseTerminalNode(eraseId);
156
157 } else {
158 InternalNode* eraseNode = _functionGraph_->_internalNodeMap_[eraseId];
159
160 if (updateParents) {
161 Link< Parent >* picle = eraseNode->parents();
162 while (picle != nullptr) {
163 setSon(picle->element().parentId, picle->element().modality, replacingId);
164 picle = picle->nextLink();
165 }
166 }
167
168 _functionGraph_->_var2NodeIdMap_[_functionGraph_->_internalNodeMap_[eraseId]->nodeVar()]
169 ->searchAndRemoveLink(eraseId);
170
171 delete _functionGraph_->_internalNodeMap_[eraseId];
172 _functionGraph_->_internalNodeMap_.erase(eraseId);
173 }
174
175 _functionGraph_->_model_.eraseNode(eraseId);
176
177 if (_functionGraph_->_root_ == eraseId) _functionGraph_->_root_ = replacingId;
178 }
void eraseNode(NodeId id, NodeId replacingId=0, bool updateParents=true)
Erases a node from the diagram.
void setSon(const NodeId &node, const Idx &modality, const NodeId &sonNode)
Sets nodes son for given modality to designated son node.
#define GUM_ERROR(type, msg)
Definition exceptions.h:72

◆ migrateNode_()

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
INLINE void gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::migrateNode_ ( const NodeId & x,
const NodeId & y )
protected

Remaps all arcs going to ou going from the first given node to the second node, then delete first node.

Parameters
xThe variable from which all arcs are removed.
yThe variable for which all of x arcs are added.

Definition at line 413 of file multiDimFunctionGraphManager_tpl.h.

415 {
416 InternalNode* org = _functionGraph_->_internalNodeMap_[origin];
417 // Upating parents after the change
418 Link< Parent >* picle = org->parents();
419 while (picle != nullptr) {
420 setSon(picle->element().parentId, picle->element().modality, destination);
421 picle = picle->nextLink();
422 }
423
424 // Updating sons after the change
425 for (Idx i = 0; i < org->nbSons(); ++i)
426 if (_functionGraph_->_internalNodeMap_.exists(org->son(i)))
427 _functionGraph_->_internalNodeMap_[org->son(i)]->removeParent(origin, i);
428
429 delete org;
430 _functionGraph_->_internalNodeMap_.erase(origin);
431 _functionGraph_->_model_.eraseNode(origin);
432
433 if (_functionGraph_->root() == origin) this->setRootNode(destination);
434 }
void setRootNode(const NodeId &root)
Sets root node of decision diagram.

References _functionGraph_, gum::Link< T >::element(), migrateNode_(), gum::InternalNode::nbSons(), gum::Link< T >::nextLink(), gum::InternalNode::parents(), setRootNode(), setSon(), and gum::InternalNode::son().

Referenced by migrateNode_(), and reduce_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ minimizeSize()

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
void gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::minimizeSize ( )

Performs a sifting in search of a(local) minimal size.

Definition at line 225 of file multiDimFunctionGraphManager_tpl.h.

225 {
226 // Ordering variables by number of nodes asssociated to them
230 = _functionGraph_->variablesSequence().beginSafe();
231 varIter != _functionGraph_->variablesSequence().endSafe();
232 ++varIter) {
233 const Link< NodeId >* curElem = _functionGraph_->_var2NodeIdMap_[*varIter]->list();
234 Idx nbElem = 0;
235 for (; curElem != nullptr; nbElem++, curElem = curElem->nextLink())
236 ;
237 varLvlSize.insert(*varIter, nbElem);
238 siftingSeq.insert(*varIter);
239 Idx pos = siftingSeq.pos(*varIter);
240 while (pos > 0 && varLvlSize[siftingSeq.atPos(pos - 1)] > nbElem) {
241 siftingSeq.swap(pos - 1, pos);
242 pos--;
243 }
244 }
245
246 // Sifting var par var
248 sifIter != siftingSeq.endSafe();
249 ++sifIter) {
250 // Initialization
251 Idx currentPos = _functionGraph_->variablesSequence().pos(*sifIter);
252 Idx bestSize = _functionGraph_->realSize();
254
255
256 // Sifting towards upper places
257 while (currentPos > 0) {
259 currentPos = _functionGraph_->variablesSequence().pos(*sifIter);
260 if (_functionGraph_->realSize() < bestSize) {
262 bestSize = _functionGraph_->realSize();
263 }
264 }
265
266 // Sifting towards lower places
269 currentPos = _functionGraph_->variablesSequence().pos(*sifIter);
270 if (_functionGraph_->realSize() < bestSize) {
272 bestSize = _functionGraph_->realSize();
273 }
274 }
275
277 }
278 }
void moveTo(const DiscreteVariable *x, Idx desiredPos)
Changes var position in variable sequence.

References MultiDimFunctionGraphManager(), and minimizeSize().

Referenced by minimizeSize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ moveTo()

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
void gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::moveTo ( const DiscreteVariable * x,
Idx desiredPos )

Changes var position in variable sequence.

Parameters
xThe varaible to change.
desiredPosThe new posiition.

Definition at line 282 of file multiDimFunctionGraphManager_tpl.h.

284 {
285 // First we determine the position of both variable
286 // We also determine which one precede the other
287 if (_functionGraph_->variablesSequence().pos(movedVar) > desiredPos)
288 for (Idx currentPos = _functionGraph_->variablesSequence().pos(movedVar);
290 currentPos--) {
291 const DiscreteVariable* preVar = _functionGraph_->variablesSequence().atPos(currentPos - 1);
292 if (_functionGraph_->_var2NodeIdMap_[preVar]->list()
293 && _functionGraph_->_var2NodeIdMap_[movedVar]->list())
296 }
297 else
298 for (Idx currentPos = _functionGraph_->variablesSequence().pos(movedVar);
300 currentPos++) {
301 const DiscreteVariable* suiVar = _functionGraph_->variablesSequence().atPos(currentPos + 1);
302 if (_functionGraph_->_var2NodeIdMap_[suiVar]->list()
303 && _functionGraph_->_var2NodeIdMap_[movedVar]->list())
306 }
307 }
void _adjacentSwap_(const DiscreteVariable *x, const DiscreteVariable *y)
Swap two adjacent variable.

References moveTo().

Referenced by moveTo().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ nodeRedundancyCheck_()

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
INLINE NodeId gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::nodeRedundancyCheck_ ( const DiscreteVariable * var,
NodeId * sonsMap )
protected

Check for redundancy.

Checks if a similar node does not already exists in the graph or if it has the same child for every variable value. If no node is a match, this node is added to the graph.

Warning
: will free by itslef sonsMap if a match exists.
Parameters
varThe node to add in the graph.
sonsMapThe node sons.
Returns
Returns the nodes id in the graph.

Definition at line 440 of file multiDimFunctionGraphManager_tpl.h.

442 {
444
445 if (_isRedundant_(var, sonsIds)) {
446 SOA_DEALLOCATE(sonsIds, sizeof(NodeId) * var->domainSize());
447 } else {
449 if (newNode == 0) {
451 } else {
452 SOA_DEALLOCATE(sonsIds, sizeof(NodeId) * var->domainSize());
453 }
454 }
455
456 return newNode;
457 }
NodeId addInternalNode_(const DiscreteVariable *var, NodeId *sons)
Adds an internal node.

References _checkIsomorphism_(), _isRedundant_(), addInternalNode_(), gum::DiscreteVariable::domainSize(), nodeRedundancyCheck_(), and SOA_DEALLOCATE.

Referenced by gum::MultiDimFunctionGraphROManager< GUM_SCALAR, TerminalNodePolicy >::addInternalNode(), and nodeRedundancyCheck_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reduce()

template<typename GUM_SCALAR, template< typename > class TerminalNodePolicy>
virtual void gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::reduce ( )
pure virtual

Ensures that every isomorphic subgraphs are merged together.

Implemented in gum::MultiDimFunctionGraphROManager< GUM_SCALAR, TerminalNodePolicy >, and gum::MultiDimFunctionGraphTreeManager< GUM_SCALAR, TerminalNodePolicy >.

Referenced by gum::AdaptiveRMaxPlaner::_makeRMaxFunctionGraphs_(), and gum::MultiDimFunctionGraphGenerator::generate().

Here is the caller graph for this function:

◆ reduce_()

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
INLINE void gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::reduce_ ( )
protected

Ensures that every isomorphic subgraphs are merged together.

Definition at line 495 of file multiDimFunctionGraphManager_tpl.h.

495 {
496 Link< NodeId >* currentNodeId = nullptr;
497 Link< NodeId >* nextNodeId = nullptr;
498 InternalNode* currentNode = nullptr;
499 bool theSame = true;
501
503 = _functionGraph_->variablesSequence().rbegin();
504 varIter != _functionGraph_->variablesSequence().rend();
505 --varIter) {
506 currentNodeId = _functionGraph_->_var2NodeIdMap_[*varIter]->list();
507
508 while (currentNodeId != nullptr) {
509 nextNodeId = currentNodeId->nextLink();
510 currentNode = _functionGraph_->_internalNodeMap_[currentNodeId->element()];
511
512 // First isomorphism to handle is the one where all node children are
513 // the same
514 theSame = true;
515 for (currentInd = 1; currentInd < (*varIter)->domainSize(); currentInd++) {
516 if (currentNode->son(currentInd) != currentNode->son(0)) {
517 theSame = false;
518 break;
519 }
520 }
521
522 if (theSame == true) {
523 migrateNode_(currentNodeId->element(), currentNode->son(0));
524 _functionGraph_->_var2NodeIdMap_[*varIter]->searchAndRemoveLink(currentNodeId->element());
526 continue;
527 }
528
529 // Second isomorphism to handle is the one where two nodes have same
530 // variable and same children
531 if (nextNodeId) {
533 InternalNode* anotherNode = nullptr;
534 Idx modality = 0;
535 while (anotherNodeId->nextLink() != nullptr) {
536 nextNodeId = anotherNodeId->nextLink();
537 anotherNode = _functionGraph_->_internalNodeMap_[anotherNodeId->element()];
538
539 // Check on the other sons
540 for (modality = 0; modality < (*varIter)->domainSize(); ++modality) {
541 if (anotherNode->son(modality) != currentNode->son(modality)) break;
542 if (modality == (*varIter)->domainSize() - 1) {
543 migrateNode_(anotherNodeId->element(), currentNodeId->element());
544 _functionGraph_->_var2NodeIdMap_[*varIter]->searchAndRemoveLink(
545 anotherNodeId->element());
546 }
547 }
548
550 }
551 }
552 currentNodeId = currentNodeId->nextLink();
553 }
554 }
555 }

References _functionGraph_, gum::Link< T >::element(), migrateNode_(), gum::Link< T >::nextLink(), reduce_(), and gum::InternalNode::son().

Referenced by gum::MultiDimFunctionGraphROManager< GUM_SCALAR, TerminalNodePolicy >::reduce(), and reduce_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setRootNode()

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
INLINE void gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::setRootNode ( const NodeId & root)

Sets root node of decision diagram.

Parameters
rootThe node to set as root.

Definition at line 76 of file multiDimFunctionGraphManager_tpl.h.

77 {
78 _functionGraph_->_root_ = root;
79 }

References _functionGraph_.

Referenced by gum::AdaptiveRMaxPlaner::_makeRMaxFunctionGraphs_(), gum::MultiDimFunctionGraphGenerator::generate(), and migrateNode_().

Here is the caller graph for this function:

◆ setSon()

template<typename GUM_SCALAR, template< class > class TerminalNodePolicy>
INLINE void gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::setSon ( const NodeId & node,
const Idx & modality,
const NodeId & sonNode )

Sets nodes son for given modality to designated son node.

Parameters
nodeThe node to which a node is added.
modalityThe modality for which sonNode is added to node.
sonNodeThe node to add as a son to node.

Definition at line 182 of file multiDimFunctionGraphManager_tpl.h.

185 {
186 // Ensuring that both nodes exists in the graph
187 if (!_functionGraph_->_model_.exists(node))
188 GUM_ERROR(NotFound, "Node : " << node << " doesn't exists in the graph")
190 GUM_ERROR(NotFound, "Node : " << sonNode << " doesn't exists in the graph")
191
192 // Check if starting node is not terminal
194 GUM_ERROR(InvalidNode, "You cannot insert an arc from terminal node : " << node)
195
196 // Check if associated modality is lower than node bound variable domain
197 // size
201 "Modality " << modality << "is higher than domain size "
203 << "minus 1 of variable "
205
206 // Check if variable order is respected
214 << " is after variable "
216 << "in Function Graph order.")
217
221 }

References _functionGraph_, GUM_ERROR, and setSon().

Referenced by gum::MultiDimFunctionGraphGenerator::generate(), migrateNode_(), and setSon().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MultiDimFunctionGraph

template<typename GUM_SCALAR, template< typename > class TerminalNodePolicy>
MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy > * MultiDimFunctionGraph ( )
friend

This friend methods from is the only way to get an instance of a manager.

See class description for more info.

Member Data Documentation

◆ _functionGraph_

template<typename GUM_SCALAR, template< typename > class TerminalNodePolicy>
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy >* gum::MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy >::_functionGraph_
private

The documentation for this class was generated from the following files: