CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
List of all members | Public Types | Public Member Functions | Private Member Functions
CombinationGenerator< T > Class Template Reference

#include <CombinationGenerator.h>

Public Types

typedef std::vector< TCollection
 
typedef std::vector< CollectionCombination
 
typedef std::vector< CombinationVectorOfCombinations
 

Public Member Functions

std::vector< Combinationcombinations (const Collection &data, int numberOfCollections) const
 
std::vector< Combinationcombinations (const Collection &data, const PartitionGenerator::Partition &partition) const
 
std::vector< Combinationcombinations (const Collection &data) const
 

Private Member Functions

std::vector< CombinationseparateOneElement (const Collection &data) const
 
VectorOfCombinations splitInTwoCollections (const Collection &data, int sizeFirst) const
 

Detailed Description

template<class T>
class CombinationGenerator< T >

Class to compute all distinct Combinations of a collection 'data' of objects of type 'T'. A Combination is a set of collections, each collection containing one or more objects, with any object in 'data' assigned to exactly one collection.

Definition at line 19 of file CombinationGenerator.h.

Member Typedef Documentation

template<class T >
typedef std::vector<T> CombinationGenerator< T >::Collection

Definition at line 23 of file CombinationGenerator.h.

template<class T >
typedef std::vector<Collection> CombinationGenerator< T >::Combination

Definition at line 25 of file CombinationGenerator.h.

template<class T >
typedef std::vector<Combination> CombinationGenerator< T >::VectorOfCombinations

Definition at line 26 of file CombinationGenerator.h.

Member Function Documentation

template<class T >
std::vector<Combination> CombinationGenerator< T >::combinations ( const Collection data,
int  numberOfCollections 
) const
inline

Create combinations obtained by dividing 'data' according to all partitions with 'numberOfCollections' collections.

Definition at line 32 of file CombinationGenerator.h.

References begin, AlCaHLTBitMon_QueryRunRegistry::data, and PartitionGenerator::sortedPartitions().

Referenced by CombinationGenerator< T >::combinations(), CombinationGenerator< T >::separateOneElement(), and CombinationGenerator< T >::splitInTwoCollections().

33  {
34  std::vector<Combination> combinations;
35  Collection sorted = data;
36 
37  // Sort if needed
38  if (prev_permutation(sorted.begin(), sorted.end())) {
39  sort(sorted.begin(), sorted.end());
40  }
41 
42  // Create sorted partitions
43  PartitionGenerator aPartitionGenerator;
44  std::vector< std::vector<PartitionGenerator::Partition> > partitions
45  = aPartitionGenerator.sortedPartitions(data.size());
46 
47  // Use partitions of size 'numberOfCollections' only
48  for (std::vector<PartitionGenerator::Partition>::const_iterator idiv
49  = partitions[numberOfCollections-1].begin();
50  idiv != partitions[numberOfCollections-1].end(); idiv++) {
51 
52  const PartitionGenerator::Partition& partition = *idiv;
53  std::vector<Combination> subCombinations
54  = this->combinations(data, partition);
55  for ( typename std::vector<Combination>::const_iterator iComb
56  = subCombinations.begin();
57  iComb != subCombinations.end(); iComb++) {
58  combinations.push_back(*iComb);
59  }
60  }
61  return combinations;
62  }
std::vector< std::vector< Partition > > sortedPartitions(int collectionSize, int minCollectionSize=1) const
std::vector< Combination > combinations(const Collection &data, int numberOfCollections) const
std::vector< int > Partition
std::vector< T > Collection
#define begin
Definition: vmac.h:30
template<class T >
std::vector<Combination> CombinationGenerator< T >::combinations ( const Collection data,
const PartitionGenerator::Partition partition 
) const
inline

Create all combinations obtained by dividing 'data' according to Partition 'partition'.

Definition at line 69 of file CombinationGenerator.h.

References bookConverter::comb, CombinationGenerator< T >::combinations(), AlCaHLTBitMon_QueryRunRegistry::data, relval_2017::k, findQualityFiles::size, and CombinationGenerator< T >::splitInTwoCollections().

71  {
72 
73  std::vector<Combination> combinations;
74 
75  // Check that sum of collection sizes in 'partition'
76  // amounts to number of elements in 'data'
77  int nElts = 0;
78  for (PartitionGenerator::Partition::const_iterator iSize
79  = partition.begin(); iSize != partition.end(); iSize++) {
80  nElts += *iSize;
81  }
82  if (nElts != data.size()) return combinations;
83 
84  Collection sortedData = data;
85  // Sort if needed
86  if (prev_permutation(sortedData.begin(), sortedData.end())) {
87  sort(sortedData.begin(), sortedData.end());
88  }
89 
90  // Create initial combination and put it on the stack
92  comb.push_back(sortedData);
93  if (partition.size() == 1) {
94  // Return only one combination with only one collection
95  combinations.push_back(comb);
96  return combinations;
97  }
98  std::stack<Combination> cStack;
99  cStack.push(comb);
100 
101  // Sort partitions by size
102  // Let 'sortedPartition' = ( n0, n1,... nk, nk+1,... nm )
103  // Ordering is >= to speed up partitioning: n0 >= n1 >=... >= nm
104  PartitionGenerator::Partition sortedPartition = partition;
105  sort(sortedPartition.begin(), sortedPartition.end(), std::greater_equal<int>());
106 
107  while (!cStack.empty()) {
108 
109  // 'combination' popped out of the stack
110  Combination combination = cStack.top(); cStack.pop();
111 
112  // At this stage 'combination' is made of collections
113  // of sizes ( n0+n1+...+nk, nk+1,... nm )
114  // Now generate all combinations obtained by splitting
115  // the first collection of 'combination' in two,
116  // according to Partition 'biPartition' = (n0+n1+...+nk-1, nk)
117  int k = sortedPartition.size() - combination.size();
118  int size = 0;
119  for (int iColl = 0; iColl != k; iColl++) {
120  size += sortedPartition[iColl];
121  }
122  PartitionGenerator::Partition biPartition(2);
123  biPartition[0] = size;
124  biPartition[1] = sortedPartition[k];
125 
126  VectorOfCombinations subCombinations
127  = splitInTwoCollections(combination[0], biPartition[0]);
128  for (typename std::vector<Combination>::const_iterator iComb = subCombinations.begin();
129  iComb != subCombinations.end(); iComb++) {
130 
131  // Check ordering of successive bins of equal size
132  if (combination.size() > 1) {
133  if ((*iComb)[1].size() == combination[1].size()) {
134  Collection adjBins;
135  adjBins.push_back((*iComb)[1][0]);
136  adjBins.push_back(combination[1][0]);
137  // Drop 'combination' if successive bins of equal size not ordered
138  // i.e. if previous permutation exists
139  if (prev_permutation(adjBins.begin(), adjBins.end())) continue;
140  }
141  }
142 
143  // Append remaining collections of 'combination'
144  Combination merged = *iComb;
145  typename Combination::const_iterator it = combination.begin(); it++;
146  for ( ; it != combination.end(); it++) { merged.push_back(*it); }
147 
148  // Store combination 'merged' if partitioning is complete,
149  // otherwise put it on the stack for further partitioning.
150  if (merged.size() == sortedPartition.size()) {
151  combinations.push_back(merged);
152  } else {
153  cStack.push(merged);
154  }
155  }
156  }
157  return combinations;
158  }
VectorOfCombinations splitInTwoCollections(const Collection &data, int sizeFirst) const
std::vector< Combination > combinations(const Collection &data, int numberOfCollections) const
dictionary comb
std::vector< Collection > Combination
std::vector< int > Partition
std::vector< T > Collection
std::vector< Combination > VectorOfCombinations
tuple size
Write out results.
template<class T >
std::vector<Combination> CombinationGenerator< T >::combinations ( const Collection data) const
inline

Create all combinations of elements from 'data'.

Definition at line 163 of file CombinationGenerator.h.

References CombinationGenerator< T >::combinations(), AlCaHLTBitMon_QueryRunRegistry::data, and PartitionGenerator::partitions().

164  {
165 
166  std::vector<Combination> combinations;
167  Collection sorted = data;
168  // Sort if needed
169  if (prev_permutation(sorted.begin(), sorted.end())) {
170  sort(sorted.begin(), sorted.end());
171  }
172 
173  PartitionGenerator aPartitionGenerator;
174  std::vector<PartitionGenerator::Partition> partitions
175  = aPartitionGenerator.partitions(data.size());
176 
177  for (std::vector<PartitionGenerator::Partition>::const_iterator idiv
178  = partitions.begin(); idiv != partitions.end(); idiv++) {
179  const PartitionGenerator::Partition& partition = *idiv;
180 
181  std::vector<Combination> subCombinations
182  = this->combinations(data, partition);
183  for ( typename std::vector<Combination>::const_iterator iComb
184  = subCombinations.begin();
185  iComb != subCombinations.end(); iComb++) {
186  combinations.push_back(*iComb);
187  }
188  }
189  return combinations;
190  }
std::vector< Partition > partitions(int collectionSize, int minCollectionSize=1) const
std::vector< Combination > combinations(const Collection &data, int numberOfCollections) const
std::vector< int > Partition
std::vector< T > Collection
template<class T >
std::vector<Combination> CombinationGenerator< T >::separateOneElement ( const Collection data) const
inlineprivate

Create all combinations obtained by dividing 'data' in two collections, the second one having only one element.

Definition at line 253 of file CombinationGenerator.h.

References coll, bookConverter::comb, CombinationGenerator< T >::combinations(), i, j, and trackerHitRTTI::single.

Referenced by CombinationGenerator< T >::splitInTwoCollections().

254  {
255  std::vector<Combination> combinations;
256  for ( typename Collection::const_iterator i = data.begin(); i != data.end(); i++) {
258  Collection single; single.push_back(*i);
259  Collection coll;
260  typename Collection::const_iterator j = data.begin();
261  for ( ; j != i; j++) { coll.push_back(*j); }
262  j++;
263  for ( ; j != data.end(); j++) { coll.push_back(*j); }
264  comb.push_back(coll); comb.push_back(single);
265  combinations.push_back(comb);
266  }
267  return combinations;
268  }
int i
Definition: DBlmapReader.cc:9
std::vector< Combination > combinations(const Collection &data, int numberOfCollections) const
dictionary comb
std::vector< Collection > Combination
int j
Definition: DBlmapReader.cc:9
JetCorrectorParametersCollection coll
Definition: classes.h:10
std::vector< T > Collection
template<class T >
VectorOfCombinations CombinationGenerator< T >::splitInTwoCollections ( const Collection data,
int  sizeFirst 
) const
inlineprivate

Create all combinations obtained by dividing 'data' in two collections, the first one being of size 'sizeFirst'

Definition at line 198 of file CombinationGenerator.h.

References runEdmFileComparison::collection, bookConverter::comb, CombinationGenerator< T >::combinations(), edm::second(), CombinationGenerator< T >::separateOneElement(), and findQualityFiles::size.

Referenced by CombinationGenerator< T >::combinations().

200  {
201  std::vector<Combination> combinations;
202  std::stack<Combination> cStack;
203 
204  // Create first combination with 2 partitions
205  Combination comb; comb.push_back(data); comb.push_back(Collection());
206  cStack.push(comb);
207 
208  while (!cStack.empty()) {
209  Combination combination = cStack.top();
210  cStack.pop();
211 
212  Collection collection = combination[0];
213  std::vector<Combination> subCombinations = separateOneElement(collection);
214 
215  for ( typename std::vector<Combination>::const_iterator iComb = subCombinations.begin();
216  iComb != subCombinations.end(); iComb++) {
217 
218  Collection second = combination[1];
219  second.push_back((*iComb)[1][0]);
220 
221  // Abandon current combination if not ordered,
222  // i.e. if previous permutation exists
223  bool ordered = !prev_permutation(second.begin(), second.end());
224  if (!ordered) continue;
225  next_permutation(second.begin(), second.end());
226 
227  if ((*iComb)[0].size() == second.size()) {
228  Collection adjBins;
229  adjBins.push_back((*iComb)[0][0]);
230  adjBins.push_back(second[0]);
231  // Abandon current combination if successive bins of equal size
232  // not ordered, i.e. if previous permutation exists
233  if (prev_permutation(adjBins.begin(), adjBins.end())) continue;
234  }
235 
236  Combination stored;
237  stored.push_back((*iComb)[0]);
238  stored.push_back(second);
239 
240  if (stored[0].size() == sizeFirst) {
241  combinations.push_back(stored);
242  } else {
243  cStack.push(stored);
244  }
245  }
246  }
247  return combinations;
248  }
U second(std::pair< T, U > const &p)
std::vector< Combination > combinations(const Collection &data, int numberOfCollections) const
dictionary comb
std::vector< Collection > Combination
std::vector< T > Collection
std::vector< Combination > separateOneElement(const Collection &data) const
tuple size
Write out results.