a Code for the Combination of Indirect and Direct Constraints on High Energy Physics Models Logo
BOL::BalancedPartitioner< ClassToBeSorted > Class Template Reference

#include <BalancedPartitioner.hpp>

Detailed Description

template<typename ClassToBeSorted>
class BOL::BalancedPartitioner< ClassToBeSorted >

Definition at line 38 of file BalancedPartitioner.hpp.

Public Member Functions

 BalancedPartitioner (double(*weightGetter)(ClassToBeSorted const &))
 
double getHigherWeight () const
 
std::vector< unsigned int > const & getHigherWeightPartitionIndices () const
 
double getLowerWeight () const
 
std::vector< unsigned int > const & getLowerWeightPartitionIndices () const
 
void makeMinimumDifferencePartition (std::vector< ClassToBeSorted > const &vectorToBeSorted)
 
 ~BalancedPartitioner ()
 

Protected Types

typedef std::list< BalancedPartitionCandidate * >::iterator CandidateListIterator
 
typedef std::vector< unsignedint >::const_iterator CandidateVectorConstIterator
 
typedef std::vector< ClassToBeSorted >::iterator ClassToBeSortedIterator
 
typedef std::pair< unsigned int, double > IndexWithWeight
 
typedef std::list< IndexWithWeight >::const_iterator IndexWithWeightListConstIterator
 
typedef std::list< IndexWithWeight >::iterator IndexWithWeightListIterator
 

Protected Member Functions

void clearSavedCandidates ()
 
void fillVectorFromBestCandidate (std::vector< unsigned int > &partitionToBeMade)
 
void makeOtherPartition (std::vector< unsigned int > &partitionToBeMade, std::vector< unsigned int > &partitionAlreadyMade)
 

Static Protected Member Functions

static bool orderByDouble (IndexWithWeight const &firstPair, IndexWithWeight const &secondPair)
 

Protected Attributes

BalancedPartitionCandidatebestCandidateSoFar
 
std::list< BalancedPartitionCandidate * > candidatesToBuildOn
 
BalancedPartitionCandidatecurrentCandidate
 
double currentWeight
 
std::list< BalancedPartitionCandidate * > extraCandidates
 
double higherWeight
 
std::vector< unsigned int > higherWeightPartition
 
double lowerWeight
 
std::vector< unsigned int > lowerWeightPartition
 
std::list< IndexWithWeightorderedList
 
double positiveWeight
 
unsigned int sizeOfVectorToSort
 
VectorlikeArray< BalancedPartitionCandidatevectorManagingCandidateMemory
 
double(* weightGetter )(ClassToBeSorted const &)
 
double weightSum
 

Member Typedef Documentation

◆ CandidateListIterator

template<typename ClassToBeSorted >
typedef std::list<BalancedPartitionCandidate*>::iterator BOL::BalancedPartitioner< ClassToBeSorted >::CandidateListIterator
protected

Definition at line 92 of file BalancedPartitioner.hpp.

◆ CandidateVectorConstIterator

template<typename ClassToBeSorted >
typedef std::vector<unsignedint>::const_iterator BOL::BalancedPartitioner< ClassToBeSorted >::CandidateVectorConstIterator
protected

Definition at line 95 of file BalancedPartitioner.hpp.

◆ ClassToBeSortedIterator

template<typename ClassToBeSorted >
typedef std::vector<ClassToBeSorted>::iterator BOL::BalancedPartitioner< ClassToBeSorted >::ClassToBeSortedIterator
protected

Definition at line 90 of file BalancedPartitioner.hpp.

◆ IndexWithWeight

template<typename ClassToBeSorted >
typedef std::pair< unsigned int, double > BOL::BalancedPartitioner< ClassToBeSorted >::IndexWithWeight
protected

Definition at line 83 of file BalancedPartitioner.hpp.

◆ IndexWithWeightListConstIterator

template<typename ClassToBeSorted >
typedef std::list<IndexWithWeight>::const_iterator BOL::BalancedPartitioner< ClassToBeSorted >::IndexWithWeightListConstIterator
protected

Definition at line 88 of file BalancedPartitioner.hpp.

◆ IndexWithWeightListIterator

template<typename ClassToBeSorted >
typedef std::list<IndexWithWeight>::iterator BOL::BalancedPartitioner< ClassToBeSorted >::IndexWithWeightListIterator
protected

Definition at line 85 of file BalancedPartitioner.hpp.

Constructor & Destructor Documentation

◆ BalancedPartitioner()

template<typename ClassToBeSorted >
BOL::BalancedPartitioner< ClassToBeSorted >::BalancedPartitioner ( double(*)(ClassToBeSorted const &)  weightGetter)
inline

Definition at line 148 of file BalancedPartitioner.hpp.

149 :
152 lowerWeight( 0.0 ),
154 higherWeight( 0.0 ),
156 weightSum( 0.0 ),
157 positiveWeight( 0.0 ),
158 orderedList(),
159 currentCandidate( NULL ),
160 bestCandidateSoFar( NULL ),
161 currentWeight( 0.0 ),
165 {
166 // just an initialization list.
167 }
std::list< IndexWithWeight > orderedList
VectorlikeArray< BalancedPartitionCandidate > vectorManagingCandidateMemory
std::vector< unsigned int > lowerWeightPartition
std::list< BalancedPartitionCandidate * > candidatesToBuildOn
std::vector< unsigned int > higherWeightPartition
BalancedPartitionCandidate * currentCandidate
double(* weightGetter)(ClassToBeSorted const &)
std::list< BalancedPartitionCandidate * > extraCandidates
BalancedPartitionCandidate * bestCandidateSoFar

◆ ~BalancedPartitioner()

template<typename ClassToBeSorted >
BOL::BalancedPartitioner< ClassToBeSorted >::~BalancedPartitioner
inline

Definition at line 171 of file BalancedPartitioner.hpp.

172 {
173 // does nothing.
174 }

Member Function Documentation

◆ clearSavedCandidates()

template<typename ClassToBeSorted >
void BOL::BalancedPartitioner< ClassToBeSorted >::clearSavedCandidates
inlineprotected

Definition at line 582 of file BalancedPartitioner.hpp.

583 {
584 lowerWeightPartition.clear();
585 higherWeightPartition.clear();
586 orderedList.clear();
587 vectorManagingCandidateMemory.clearEntries();
588 candidatesToBuildOn.clear();
589 }

◆ fillVectorFromBestCandidate()

template<typename ClassToBeSorted >
void BOL::BalancedPartitioner< ClassToBeSorted >::fillVectorFromBestCandidate ( std::vector< unsigned int > &  partitionToBeMade)
inlineprotected

Definition at line 611 of file BalancedPartitioner.hpp.

613 {
614 partitionToBeMade = bestCandidateSoFar->getVector();
615 }
std::vector< unsigned int > & getVector()

◆ getHigherWeight()

template<typename ClassToBeSorted >
double BOL::BalancedPartitioner< ClassToBeSorted >::getHigherWeight
inline

Definition at line 573 of file BalancedPartitioner.hpp.

576 {
577 return higherWeight;
578 }

◆ getHigherWeightPartitionIndices()

template<typename ClassToBeSorted >
std::vector< unsigned int > const & BOL::BalancedPartitioner< ClassToBeSorted >::getHigherWeightPartitionIndices
inline

Definition at line 555 of file BalancedPartitioner.hpp.

567 {
569 }

◆ getLowerWeight()

template<typename ClassToBeSorted >
double BOL::BalancedPartitioner< ClassToBeSorted >::getLowerWeight
inline

Definition at line 546 of file BalancedPartitioner.hpp.

549 {
550 return lowerWeight;
551 }

◆ getLowerWeightPartitionIndices()

template<typename ClassToBeSorted >
std::vector< unsigned int > const & BOL::BalancedPartitioner< ClassToBeSorted >::getLowerWeightPartitionIndices
inline

Definition at line 528 of file BalancedPartitioner.hpp.

540 {
542 }

◆ makeMinimumDifferencePartition()

template<typename ClassToBeSorted >
void BOL::BalancedPartitioner< ClassToBeSorted >::makeMinimumDifferencePartition ( std::vector< ClassToBeSorted > const &  vectorToBeSorted)
inline

Definition at line 178 of file BalancedPartitioner.hpp.

180 {
181 // 1st, we remove all the stuff that might have been hanging around since
182 // the last partitioning:
184 weightSum = 0.0;
185
186 sizeOfVectorToSort = vectorToBeSorted.size();
187 // next we make a list of the objects with the weights (absolute values, &
188 // we also ignore any objects with zero weight) & find the total weight:
189 for( unsigned int whichIndex( 0 );
190 sizeOfVectorToSort > whichIndex;
191 ++whichIndex )
192 {
193 positiveWeight = (*weightGetter)( vectorToBeSorted[ whichIndex ] );
194 if( 0.0 > positiveWeight )
195 {
197 }
198 if( 0.0 < positiveWeight )
199 {
201 orderedList.push_back( IndexWithWeight( whichIndex,
202 positiveWeight ) );
203 }
204 }
205
206 double const halfTotalWeight( 0.5 * weightSum );
207 if( orderedList.empty() )
208 // if the given set didn't have enough objects to sort...
209 {
210 // the vectors that get returned have already been cleared.
211 lowerWeight = 0.0;
212 higherWeight = 0.0;
213 }
214 else
215 {
216 orderedList.sort( &orderByDouble );
217 // now orderedList is all the objects with non-zero weight, ordered by
218 // their absolute weights.
219
220 if( halfTotalWeight <= orderedList.back().second )
221 // if the object with greatest weight takes up half or more of the
222 // total weight by itself...
223 {
224 // it alone becomes higherWeightPartition.
225 higherWeightPartition.push_back( orderedList.back().first );
226 higherWeight = orderedList.back().second;
230 }
231 else if( orderedList.size() < 4 )
232 // or if the given set was too small to have any non-trivial
233 // partitions...
234 {
235 // the object with greatest weight alone becomes lowerWeightPartition
236 // (if it should become higherWeightPartition, it'll have happened in
237 // the previous if statement):
238 lowerWeightPartition.push_back( orderedList.back().first );
239 lowerWeight = orderedList.back().second;
243 }
244 else
245 // otherwise, we need to check all the required combinations (partitions
246 // of sizes up to half the number of objects, with weights less than half
247 // the total weight, *plus* cases where the weight is over half the total
248 // weight, if removing a single element would bring it back under half
249 // the total weight):
250 {
251 // 1st we note that the highest-weight element on its own is still the
252 // leading candidate partition:
254 bestCandidateSoFar->getVector().assign( 1,
255 orderedList.back().first );
256 lowerWeight = orderedList.back().second;
260 // now bestCandidate so far is the highest-weight element on its own, &
261 // vectorManagingCandidateMemory is holding a pointer to it in case the
262 // bestCandidateSoFar pointer gets set to pointing at a different
263 // partitionCandidate.
264
265
266 // now we start going through candidate partitions which consist of 2
267 // or more elements.
268 IndexWithWeightListConstIterator listIterator( orderedList.begin() );
269 ++listIterator;
270 // listIterator is now at the pair with the 2nd object by weight.
272 // note where the new partitionCandidate is in memory, so that we can
273 // delete it later.
275 currentCandidate->getVector().assign( 2,
276 orderedList.front().first );
277 // currentCandidate is now the set { [lowest weight element] }.
278 currentCandidate->getVector()[ 1 ] = listIterator->first;
279 // currentCandidate is now the set
280 // { [lowest weight element], [2nd-lowest weight element] }.
282 = ( orderedList.front().second + listIterator->second );
283 // the only way that this combination could have half the weight or
284 // over is if there was only 3 elements or less, which should have
285 // been caught by earlier if statements.
288
290 // if this is a better candidate than the single highest-weight
291 // object...
292 {
293 // note the weights of this new current best candidate:
296 // note the actual new best current candidate:
298 }
299
300 IndexWithWeightListConstIterator lowerWeightIterator;
301 // this is used for making new candidates of 2 elements.
302
303 // now we loop over the rest of the objects in orderedList (all but the
304 // 2 lowest-weight objects) to build all partitions with 2 or more
305 // objects.
306 // we don't bother building with partition candidates which are already
307 // over half the total weight; however, we do keep those which are over
308 // half the weight after being built from a candidate with less than
309 // half the weight, if its weight is less that the higherWeight of the
310 // best candidate so far, in which case it becomes the new best
311 // candidate.
312 // we also don't bother building candidates with more than half the
313 // total number of elements, because their partners should already have
314 // been found.
315
316 // move on to the 3rd object by weight to begin the loop:
317 ++listIterator;
318 while( orderedList.end() != listIterator )
319 // until we reach the end of orderedList...
320 {
322 candidateIterator( candidatesToBuildOn.begin() );
323 candidatesToBuildOn.end() != candidateIterator;
324 ++candidateIterator )
325 {
326 if( ( 2 * ( (*candidateIterator)->getVector().size() + 1 ) )
327 <= orderedList.size() )
328 // if we're not building a candidate that consists of too many
329 // objects...
330 {
331 currentWeight = ( (*candidateIterator)->getWeight()
332 + listIterator->second );
333
334 if( halfTotalWeight < currentWeight )
335 // if this candidate is already over half the weight, it cannot
336 // be used to build upon, so we only keep it if it's a better
337 // candidate than bestCandidateSoFar. in either case, we remove
338 // *candidateIterator from candidatesToBuildOn because it's
339 // not going to be a better candidate when paired with an
340 // object of even higher weight.
341 {
343 // if this *is* a better candidate (including not consisting
344 // of too many elements; if a candidate has half the elements
345 // but over half the weight, the its partner has half the
346 // elements & less than half the weight, so it'll be found
347 // anyway)...
348 {
349 // note the weights of this new current best candidate:
352 // make the new best candidate & manage the memory:
354 = &(vectorManagingCandidateMemory.newEnd());
355 // set the candidate's properties:
356 bestCandidateSoFar->buildFrom( *(*candidateIterator),
357 listIterator->first,
359 lowerWeight );
360 }
361 // otherwise, we don't do anything with this combination of
362 // *candidateIterator & *listIterator.
363 // in either case we remove *candidateIterator from
364 // candidatesToBuildOn because it's not going to be a better
365 // candidate when paired with an object of even higher weight.
366 candidateIterator
367 = candidatesToBuildOn.erase( candidateIterator );
368 }
369 else
370 // otherwise, currentWeight <= halfTotalWeight, so we check to
371 // see if it's a better candidate than bestCandidateSoFar, &
372 // also if we should keep it for building on, if it does not
373 // consist of too many objects already...
374 {
376 // if this *is* a better candidate...
377 {
378 // note the weights of this new current best candidate:
381 // make the new best candidate & manage the memory:
383 = &(vectorManagingCandidateMemory.newEnd());
384 // set the candidate's properties:
385 bestCandidateSoFar->buildFrom( *(*candidateIterator),
386 listIterator->first,
388 higherWeight );
389
390 if( ( 2 * ( (*candidateIterator)->getVector().size() + 2 ) )
391 <= orderedList.size() )
392 // if building on this would make a candidate that still
393 // would not consist of too many objects...
394 {
396 }
397 }
398 else if( ( 2 * ( (*candidateIterator)->getVector().size()
399 + 2 ) )
400 <= orderedList.size() )
401 // otherwise if we're building a candidate which is not the
402 // best candidate so far, but building on it would make a
403 // candidate that still would not consist of too many
404 // objects...
405 {
406 // make the new candidate & manage the memory:
408 = &(vectorManagingCandidateMemory.newEnd());
410 // set the candidate's properties:
411 currentCandidate->buildFrom( *(*candidateIterator),
412 listIterator->first,
414 // we know that ( halfTotalWeight > currentWeight )
415 ( weightSum - currentWeight ) );
416 }
417 }
418 // end of checking if the weight of this combination of
419 // *candidateIterator & *listIterator makes it worth keeping,
420 // either as bestCandidateSoFar or just as a candidate to build
421 // others from.
422 }
423 // end of if the candidate would not consist of too many objects.
424 }
425 // end of for loop over existing candidate partitions to build new
426 // partitions from with (*listIterator)->first
427
430 // all the new candidate partitions are moved from extraCandidates to
431 // candidatesToBuildOn, at the start, though that isn't important.
432
433 // now we need to build all the 2-object candidates with
434 // *listIterator & all objects before it in orderedList:
435 lowerWeightIterator = orderedList.begin();
436 while( listIterator != lowerWeightIterator )
437 {
439 = ( listIterator->second + lowerWeightIterator->second );
440 if( halfTotalWeight < currentWeight )
441 // if this candidate is already over half the weight, it cannot
442 // be used to build upon, so we only keep it if it's a better
443 // candidate than bestCandidateSoFar.
444 {
446 // if this *is* a better candidate...
447 {
448 // note the weights of this new current best candidate:
451 // make the new best candidate & manage the memory:
453 = &(vectorManagingCandidateMemory.newEnd());
454 // set the candidate's properties:
455 bestCandidateSoFar->getVector().assign( 2,
456 lowerWeightIterator->first );
457 bestCandidateSoFar->getVector()[ 1 ] = listIterator->first;
460 }
461 // otherwise, we don't do anything with this combination of
462 // *lowerWeightIterator & *listIterator, or any other
463 // *lowerWeightIterator, because they'll all have even greater
464 // weight, so we end the loop:
465 lowerWeightIterator = listIterator;
466 }
467 else
468 // otherwise, we have a new candidate to build upon, even if it's
469 // not the best candidate so far...
470 {
471 // make the new candidate & manage the memory:
474 // set the candidate's properties:
475 currentCandidate->getVector().assign( 2,
476 lowerWeightIterator->first );
477 currentCandidate->getVector()[ 1 ] = listIterator->first;
480 - currentWeight ) );
482 // if this *is* a better candidate...
483 {
484 // note the weights of this new current best candidate:
487 // note the actual new best current candidate:
489 }
490
491 // now we try the next-lowest weight pairing of *listIterator:
492 ++lowerWeightIterator;
493 }
494 // end of if-else deciding whether to create a new candidate & move
495 // on to the next pairing, or to break the loop (possibly after
496 // updating bestCandidateSoFar).
497 }
498 // end of while loop over objects in orderedList before
499 // *listIterator.
500
501 // move on to the next object by weight:
502 ++listIterator;
503 }
504 // end of while loop going over the higher-weighted objects, building
505 // all the partition candidates which can involve them.
506
507 // at this point, bestCandidateSoFar *is* the best candidate:
508 if( halfTotalWeight > bestCandidateSoFar->getWeight() )
509 {
513 }
514 else
515 {
519 }
520 }
521 }
522 // end of if-else about whether we needed to check all appropriate
523 // combinations or not.
524 }
void setWeight(double const candidateWeight)
void buildFrom(BalancedPartitionCandidate const &basePartition, unsigned int const extraIndex, double const candidateWeight, double const inverseWeight)
void setInverseWeight(double const inverseWeight)
std::pair< unsigned int, double > IndexWithWeight
static bool orderByDouble(IndexWithWeight const &firstPair, IndexWithWeight const &secondPair)
std::list< BalancedPartitionCandidate * >::iterator CandidateListIterator
void makeOtherPartition(std::vector< unsigned int > &partitionToBeMade, std::vector< unsigned int > &partitionAlreadyMade)
std::list< IndexWithWeight >::const_iterator IndexWithWeightListConstIterator
void fillVectorFromBestCandidate(std::vector< unsigned int > &partitionToBeMade)

◆ makeOtherPartition()

template<typename ClassToBeSorted >
void BOL::BalancedPartitioner< ClassToBeSorted >::makeOtherPartition ( std::vector< unsigned int > &  partitionToBeMade,
std::vector< unsigned int > &  partitionAlreadyMade 
)
inlineprotected

Definition at line 619 of file BalancedPartitioner.hpp.

625 {
626 IndexWithWeightListIterator removingIterator( orderedList.begin() );
628 alreadyUsedIterator( partitionAlreadyMade.begin() );
629 partitionAlreadyMade.end() > alreadyUsedIterator;
630 ++alreadyUsedIterator )
631 {
632 // now we look for *alreadyUsedIterator in orderedList:
633 removingIterator = orderedList.begin();
634 while( removingIterator->first != *alreadyUsedIterator )
635 {
636 ++removingIterator;
637 }
638 // now we've found *alreadyUsedIterator in orderedList.
639 orderedList.erase( removingIterator );
640 // we remove it from the list.
641 }
642 // now all the elements of partitionAlreadyMade should have been removed
643 // from orderedList.
644 for( IndexWithWeightListIterator fillingIterator( orderedList.begin() );
645 orderedList.end() != fillingIterator;
646 ++fillingIterator )
647 {
648 partitionToBeMade.push_back( fillingIterator->first );
649 }
650 }
std::list< IndexWithWeight >::iterator IndexWithWeightListIterator
std::vector< unsignedint >::const_iterator CandidateVectorConstIterator

◆ orderByDouble()

template<typename ClassToBeSorted >
bool BOL::BalancedPartitioner< ClassToBeSorted >::orderByDouble ( IndexWithWeight const &  firstPair,
IndexWithWeight const &  secondPair 
)
inlinestaticprotected

Definition at line 593 of file BalancedPartitioner.hpp.

598 {
599 if( firstPair.second <= secondPair.second )
600 {
601 return true;
602 }
603 else
604 {
605 return false;
606 }
607 }

Member Data Documentation

◆ bestCandidateSoFar

template<typename ClassToBeSorted >
BalancedPartitionCandidate* BOL::BalancedPartitioner< ClassToBeSorted >::bestCandidateSoFar
protected

Definition at line 110 of file BalancedPartitioner.hpp.

◆ candidatesToBuildOn

template<typename ClassToBeSorted >
std::list< BalancedPartitionCandidate* > BOL::BalancedPartitioner< ClassToBeSorted >::candidatesToBuildOn
protected

Definition at line 117 of file BalancedPartitioner.hpp.

◆ currentCandidate

template<typename ClassToBeSorted >
BalancedPartitionCandidate* BOL::BalancedPartitioner< ClassToBeSorted >::currentCandidate
protected

Definition at line 109 of file BalancedPartitioner.hpp.

◆ currentWeight

template<typename ClassToBeSorted >
double BOL::BalancedPartitioner< ClassToBeSorted >::currentWeight
protected

Definition at line 111 of file BalancedPartitioner.hpp.

◆ extraCandidates

template<typename ClassToBeSorted >
std::list< BalancedPartitionCandidate* > BOL::BalancedPartitioner< ClassToBeSorted >::extraCandidates
protected

Definition at line 118 of file BalancedPartitioner.hpp.

◆ higherWeight

template<typename ClassToBeSorted >
double BOL::BalancedPartitioner< ClassToBeSorted >::higherWeight
protected

Definition at line 103 of file BalancedPartitioner.hpp.

◆ higherWeightPartition

template<typename ClassToBeSorted >
std::vector< unsigned int > BOL::BalancedPartitioner< ClassToBeSorted >::higherWeightPartition
protected

Definition at line 102 of file BalancedPartitioner.hpp.

◆ lowerWeight

template<typename ClassToBeSorted >
double BOL::BalancedPartitioner< ClassToBeSorted >::lowerWeight
protected

Definition at line 101 of file BalancedPartitioner.hpp.

◆ lowerWeightPartition

template<typename ClassToBeSorted >
std::vector< unsigned int > BOL::BalancedPartitioner< ClassToBeSorted >::lowerWeightPartition
protected

Definition at line 100 of file BalancedPartitioner.hpp.

◆ orderedList

template<typename ClassToBeSorted >
std::list< IndexWithWeight > BOL::BalancedPartitioner< ClassToBeSorted >::orderedList
protected

Definition at line 107 of file BalancedPartitioner.hpp.

◆ positiveWeight

template<typename ClassToBeSorted >
double BOL::BalancedPartitioner< ClassToBeSorted >::positiveWeight
protected

Definition at line 106 of file BalancedPartitioner.hpp.

◆ sizeOfVectorToSort

template<typename ClassToBeSorted >
unsigned int BOL::BalancedPartitioner< ClassToBeSorted >::sizeOfVectorToSort
protected

Definition at line 97 of file BalancedPartitioner.hpp.

◆ vectorManagingCandidateMemory

template<typename ClassToBeSorted >
VectorlikeArray< BalancedPartitionCandidate > BOL::BalancedPartitioner< ClassToBeSorted >::vectorManagingCandidateMemory
protected

Definition at line 113 of file BalancedPartitioner.hpp.

◆ weightGetter

template<typename ClassToBeSorted >
double(* BOL::BalancedPartitioner< ClassToBeSorted >::weightGetter) (ClassToBeSorted const &)
protected

Definition at line 104 of file BalancedPartitioner.hpp.

◆ weightSum

template<typename ClassToBeSorted >
double BOL::BalancedPartitioner< ClassToBeSorted >::weightSum
protected

Definition at line 105 of file BalancedPartitioner.hpp.


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