aGrUM  0.16.0
leafAggregator.cpp
Go to the documentation of this file.
1 
29 // =======================================================
30 #include <agrum/core/math/math.h>
32 // =======================================================
33 
34 namespace gum {
35 
36  // ############################################################################
37  // Constructors / Destructors
38  // ############################################################################
39 
40  // ============================================================================
41  // Default constructor.
42  // ============================================================================
44  double similarityThreshold) :
45  __leavesCpt(idSource),
46  __similarityThreshold(similarityThreshold) {
47  GUM_CONSTRUCTOR(LeafAggregator);
49  __needsUpdate = false;
50  }
51 
52  // ============================================================================
53  // Default constructor.
54  // ============================================================================
56  __removeContext(0);
57 
58  delete __initialContext;
59 
61  __leaf2Pair.beginSafe();
62  leafIter != __leaf2Pair.endSafe();
63  ++leafIter) {
64  for (SetIteratorSafe< LeafPair* > pairIter = leafIter.val()->beginSafe();
65  pairIter != leafIter.val()->endSafe();
66  ++pairIter) {
67  LeafPair* curPair = *pairIter;
68  __leaf2Pair[curPair->otherLeaf(leafIter.key())]->erase(*pairIter);
69  leafIter.val()->erase(curPair);
70  delete curPair;
71  }
72  delete leafIter.val();
73  }
74 
75 
76  GUM_DESTRUCTOR(LeafAggregator);
77  }
78 
79  // ############################################################################
80  //
81  // ############################################################################
82 
83  // ============================================================================
84  //
85  // ============================================================================
87  Set< LeafPair* >* leafPairSet = new Set< LeafPair* >();
88  Set< LeafPair* > bag;
89 
90  // ****************************************************************************************
91  // Création et ajout des pairs de base (Feuille de base + nouvelle Feuille)
93  __leaf2Pair.cbeginSafe();
94  leafIter != __leaf2Pair.cendSafe();
95  ++leafIter) {
96  // Création de la pair et ajout dans les listes de pair des feuilles de
97  // base
98  LeafPair* p = new LeafPair(l, leafIter.key());
99  p->updateLikelyhood();
100  leafPairSet->insert(p);
101  (leafIter.val())->insert(p);
102 
103  // Ajout de la nouvelle pair au tas initial
104  __addInitialPair(p);
105 
106  bag.insert(p);
107  }
108 
109  // ****************************************************************************************
110  // Enregistrement de la nouvelle Feuille en tant que feuille de base
111  __leaf2Pair.insert(l, leafPairSet);
112 
113  // ****************************************************************************************
114  // Ajout de la feuille aux FusionContext
115 
117  __fusionSeq.beginSafe();
118  fusIter != __fusionSeq.endSafe();
119  ++fusIter) {
120  // Ajout de la nouvelle pair composée de la feuille de FusIter et de la
121  // nouvelle feuille aux FusionContext suivant
122  for (SetIteratorSafe< LeafPair* > pairIter = bag.beginSafe();
123  pairIter != bag.endSafe();
124  ++pairIter) {
125  if ((*fusIter)->leaf()->contains((*pairIter)->secondLeaf()->id())) {
126  bag >> *pairIter;
127  continue;
128  }
129 
130  if ((*fusIter)->addPair(*pairIter)) __removeContext(fusIter.pos() + 1);
131  }
132 
133  if ((*fusIter)->associateLeaf(l)) __removeContext(fusIter.pos() + 1);
134 
135  bag << (*fusIter)->leafAssociatedPair(l);
136  }
137 
138  __needsUpdate = true;
139  }
140 
141 
142  // ============================================================================
143  //
144  // ============================================================================
146  // ***********************************************************************************
147  // First we update every base pair linked to that leaf
148  Set< LeafPair* > bag(*(__leaf2Pair[l]));
149  for (SetIteratorSafe< LeafPair* > pairIter = bag.beginSafe();
150  pairIter != bag.endSafe();
151  ++pairIter) {
152  (*pairIter)->updateLikelyhood();
153  __updateInitialPair(*pairIter);
154  }
155 
156  // **********************************************************************************
157  // The we have top update FusionContext pairs associated to that leaf
158  AbstractLeaf* curLeaf = l;
160  __fusionSeq.beginSafe();
161  fusIter != __fusionSeq.endSafe();
162  ++fusIter) {
163  if ((*fusIter)->leaf()->contains(curLeaf->id())) {
164  bag.clear();
165  if ((*fusIter)->updateAllAssociatedLeaves())
166  __removeContext(fusIter.pos() + 1);
167  bag = (*fusIter)->associatedPairs();
168  curLeaf = (*fusIter)->leaf();
169  continue;
170  }
171 
172  for (SetIteratorSafe< LeafPair* > pairIter = bag.beginSafe();
173  pairIter != bag.endSafe();
174  ++pairIter) {
175  if ((*fusIter)->leaf()->contains((*pairIter)->secondLeaf()->id())
176  || (*fusIter)->leaf()->contains((*pairIter)->firstLeaf()->id())) {
177  bag >> *pairIter;
178  continue;
179  }
180 
181  if ((*fusIter)->updatePair(*pairIter)) __removeContext(fusIter.pos() + 1);
182  }
183  if ((*fusIter)->updateAssociatedLeaf(curLeaf))
184  __removeContext(fusIter.pos() + 1);
185  bag << (*fusIter)->leafAssociatedPair(curLeaf);
186  }
187 
188  return __needsUpdate;
189  }
190 
191 
192  // ============================================================================
193  //
194  // ============================================================================
196  // ***********************************************************************************
197  // First we update every base pair linked to that leaf
198  Set< LeafPair* > bag(*(__leaf2Pair[l]));
199  for (SetIteratorSafe< LeafPair* > pairIter = bag.beginSafe();
200  pairIter != bag.endSafe();
201  ++pairIter) {
202  __removeInitialPair(*pairIter);
203  (*__leaf2Pair[(*pairIter)->otherLeaf(l)]) >> *pairIter;
204  }
205 
206  // **********************************************************************************
207  // The we have top update FusionContext pairs associated to that leaf
208  Set< LeafPair* > toBeDeleted;
210  __fusionSeq.beginSafe();
211  fusIter != __fusionSeq.endSafe();
212  ++fusIter) {
213  for (SetIteratorSafe< LeafPair* > pairIter = bag.beginSafe();
214  pairIter != bag.endSafe();
215  ++pairIter) {
216  if ((*fusIter)->leaf()->contains((*pairIter)->secondLeaf()->id())
217  || (*fusIter)->leaf()->contains((*pairIter)->firstLeaf()->id())) {
218  bag >> *pairIter;
219  continue;
220  }
221 
222  if ((*fusIter)->removePair(*pairIter)) {
223  __removeContext(fusIter.pos() + 1);
224  }
225  }
226 
227  bag << (*fusIter)->leafAssociatedPair(l);
228  toBeDeleted << (*fusIter)->leafAssociatedPair(l);
229 
230  if ((*fusIter)->deassociateLeaf(l)) { __removeContext(fusIter.pos() + 1); }
231  }
232 
233  for (SetIteratorSafe< LeafPair* > pairIter = toBeDeleted.beginSafe();
234  pairIter != toBeDeleted.endSafe();
235  ++pairIter)
236  delete *pairIter;
237 
238  for (SetIteratorSafe< LeafPair* > pairIter = __leaf2Pair[l]->beginSafe();
239  pairIter != __leaf2Pair[l]->endSafe();
240  ++pairIter)
241  delete *pairIter;
242  delete __leaf2Pair[l];
243  __leaf2Pair.erase(l);
244 
245  __needsUpdate = true;
246  }
247 
248 
249  // ============================================================================
250  //
251  // ============================================================================
253  LeafPair* nextPair = __initialContext->top();
256  if (!__fusionSeq.empty()) {
257  nextPair = __fusionSeq.back()->top();
258  pb = __fusionSeq.back()->beginPairs();
259  pe = __fusionSeq.back()->endPairs();
260  }
261 
262 
263  while (nextPair && nextPair->likelyhood() < __similarityThreshold) {
264  AbstractLeaf* newLeaf = nextPair->convert2Leaf(__leavesCpt->addNode());
265  FusionContext< false >* newContext = new FusionContext< false >(newLeaf);
266 
267  for (pair_iterator pairIter = pb; pairIter != pe; ++pairIter) {
268  if (!newLeaf->contains(pairIter.key()->firstLeaf()->id())
269  && !newLeaf->contains(pairIter.key()->secondLeaf()->id()))
270  newContext->addPair(pairIter.key());
271  if (!newLeaf->contains(pairIter.key()->firstLeaf()->id())
272  && !newContext->containsAssociatedLeaf(pairIter.key()->firstLeaf()))
273  newContext->associateLeaf(pairIter.key()->firstLeaf());
274  if (!newLeaf->contains(pairIter.key()->secondLeaf()->id())
275  && !newContext->containsAssociatedLeaf(pairIter.key()->secondLeaf()))
276  newContext->associateLeaf(pairIter.key()->secondLeaf());
277  }
278 
279  __fusionSeq.insert(newContext);
280  nextPair = __fusionSeq.back()->top();
281  pb = __fusionSeq.back()->beginPairs();
282  pe = __fusionSeq.back()->endPairs();
283  }
284  __needsUpdate = false;
285  }
286 
287 
291  __fusionSeq.rbeginSafe();
292  fusIter != __fusionSeq.rendSafe();
293  --fusIter) {
294  bool alreadyIn = false;
296  retMap.beginSafe();
297  mapIter != retMap.endSafe();
298  ++mapIter)
299  if (mapIter.val()->contains((*fusIter)->leaf()->id())) {
300  alreadyIn = true;
301  break;
302  }
303  if (!alreadyIn) retMap.insert((*fusIter)->leaf()->id(), (*fusIter)->leaf());
304  }
305 
307  __leaf2Pair.beginSafe();
308  leafIter != __leaf2Pair.endSafe();
309  ++leafIter) {
311  retMap.beginSafe();
312  mapIter != retMap.endSafe();
313  ++mapIter)
314  if (mapIter.val()->contains(leafIter.key()->id())) {
315  retMap.insert(leafIter.key()->id(), mapIter.val());
316  break;
317  }
318  if (!retMap.exists(leafIter.key()->id()))
319  retMap.insert(leafIter.key()->id(), leafIter.key());
320  }
321 
322  return retMap;
323  }
324 
325 
326  std::string LeafAggregator::toString() {
327  std::stringstream ss;
328  ss << "################\nTas Initial : " << std::endl
329  << __initialContext->toString() << std::endl;
330 
331  for (auto fusIter = __fusionSeq.beginSafe(); fusIter != __fusionSeq.endSafe();
332  ++fusIter) {
333  ss << "################\nTas " << fusIter.pos() << " : " << std::endl
334  << (*fusIter)->toString();
335  }
336 
337  return ss.str();
338  }
339 
340  // ############################################################################
341  //
342  // ############################################################################
343 
344  // ============================================================================
345  //
346  // ============================================================================
348  for (Idx i = __fusionSeq.size() - 1; !__fusionSeq.empty() && i >= startingPos;
349  --i) {
350  __leavesCpt->eraseNode(__fusionSeq.atPos(i)->leaf()->id());
351  delete __fusionSeq.atPos(i);
352  __fusionSeq.erase(__fusionSeq.atPos(i));
353  }
354 
355  __needsUpdate = true;
356  }
357 
358 
359  // ============================================================================
360  //
361  // ============================================================================
363  bool res = __initialContext->addPair(p);
364  if (res) __removeContext(0);
365  }
366 
367 
368  // ============================================================================
369  //
370  // ============================================================================
372  bool res = __initialContext->updatePair(p);
373  if (res) __removeContext(0);
374  }
375 
376  // ============================================================================
377  //
378  // ============================================================================
380  bool res = __initialContext->removePair(p);
381  if (res) __removeContext(0);
382  }
383 
384 } // namespace gum
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
virtual bool contains(NodeId testedId) const
Returns true if abstractleaf has leaf in it.
Definition: abstractLeaf.h:93
Safe iterators for Sequence.
Definition: sequence.h:1206
void __removeInitialPair(LeafPair *)
AbstractLeaf * convert2Leaf(NodeId leafId) const
Returns a leaf matching data and having given id as id.
Definition: leafPair.h:115
const iterator_safe & endSafe() noexcept
Returns the safe iterator pointing to the end of the hashtable.
Safe iterators for the Set classDevelopers may consider using Set<x>::iterator_safe instead of SetIte...
Definition: set.h:811
std::string toString()
<agrum/FMDP/learning/FunctionGraph/leafAggregator.h>
bool removePair(LeafPair *p)
pair_iterator endPairs()
<agrum/FMDP/learning/datastructure/leaves/abstractLeaf.h>
Definition: abstractLeaf.h:53
Safe Const Iterators for hashtables.
Definition: hashTable.h:1918
<agrum/FMDP/learning/datastructure/leaves/leafPair.h>
Definition: leafPair.h:51
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
NodeGraphPart * __leavesCpt
void __addInitialPair(LeafPair *)
Safe Iterators for hashtables.
Definition: hashTable.h:2220
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
virtual NodeId addNode()
insert a new node and return its id
The class for generic Hash Tables.
Definition: hashTable.h:679
Representation of a setA Set is a structure that contains arbitrary elements.
Definition: set.h:165
const iterator_safe & endSafe() const noexcept
The usual safe end iterator to parse the set.
Definition: set_tpl.h:502
~LeafAggregator()
Default destructor.
Sequence< FusionContext< false > *> __fusionSeq
AbstractLeaf * otherLeaf(AbstractLeaf *l) const
Definition: leafPair.h:119
LeafAggregator(NodeGraphPart *idSource, double similarityThreshold)
Default constructor.
Class for node sets in graph.
bool addPair(LeafPair *p)
HashTable< NodeId, AbstractLeaf *> leavesMap()
FusionContext< true > * __initialContext
HashTable< AbstractLeaf *, Set< LeafPair *> *> __leaf2Pair
iterator_safe beginSafe()
Returns the safe iterator pointing to the beginning of the hashtable.
iterator_safe beginSafe() const
The usual safe begin iterator to parse the set.
Definition: set_tpl.h:488
bool containsAssociatedLeaf(AbstractLeaf *l)
Definition: fusionContext.h:96
LeafPair * top()
Size Idx
Type for indexes.
Definition: types.h:53
void removeLeaf(AbstractLeaf *)
void clear()
Removes all the elements, if any, from the set.
Definition: set_tpl.h:375
bool associateLeaf(AbstractLeaf *l)
std::string toString()
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
bool updateLeaf(AbstractLeaf *)
double likelyhood()
Updates GStatistic.
Definition: leafPair.cpp:77
void addLeaf(AbstractLeaf *)
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:613
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
bool updatePair(LeafPair *p)
void updateLikelyhood()
Updates GStatistic.
Definition: leafPair.cpp:42
pair_iterator beginPairs()
virtual void eraseNode(const NodeId id)
erase the node with the given id
void __updateInitialPair(LeafPair *)