Advertisement
Shaktal

CombinationGenerator.cpp

Jul 29th, 2011
322
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.06 KB | None | 0 0
  1. #include "CombinationGenerator.h"
  2. #include <cassert>
  3.  
  4. CombinationGenerator* g_pCombinationGen = nullptr;
  5.  
  6. //====================================================
  7. // Purpose: Initialize Combination generator with a
  8. //      specified n (number of elements) with k
  9. //      elements per combination
  10. //====================================================
  11. void CombinationGenerator::Initialize( int n, int k )
  12. {
  13.  
  14.     // for nCk, n must be greater k, and n must be greater than 1:
  15.     assert( n >= k && n > 1 );
  16.  
  17.     this->n = n;
  18.     this->k = k;
  19.     this->m_iNumLeft = this->m_iNumCombinations = ComputeBinomialCoefficient( n, k );
  20.  
  21.     // Clear our vector to be sure:
  22.     m_vecCurrCombination.clear();
  23.  
  24.     for( int i = 0; i < k; i++ )
  25.     {
  26.         m_vecCurrCombination.push_back( i );
  27.     }
  28.  
  29. }
  30.  
  31. //====================================================
  32. // Purpose: Initializer overload, number of comb.
  33. //      have already been calculated.
  34. //====================================================
  35. void CombinationGenerator::Initialize( int n, int k, unsigned long long numCombinations )
  36. {
  37.     assert( n >= k && n > 1);
  38.     this->n = n;
  39.     this->k = k;
  40.  
  41.     this->m_iNumLeft = this->m_iNumCombinations = numCombinations;
  42.  
  43.  
  44.     m_vecCurrCombination.clear();
  45.  
  46.     for( int i = 0; i < k; i++ )
  47.     {
  48.         m_vecCurrCombination.push_back(i);
  49.     }
  50.  
  51. }
  52.  
  53. //====================================================
  54. // Purpose: Calculate nCk using the minimum amount of
  55. //      memory:
  56. //====================================================
  57. unsigned long long CombinationGenerator::ComputeBinomialCoefficient( int n, int k )
  58. {
  59.     // Another run-time assert in case we decide to call this separately at some point:
  60.     assert( n > k && n > 1 );
  61.  
  62.     // Exploit the symmetry in the line x = k/2:
  63.     if( k > n - k )
  64.         k = n - k;
  65.  
  66.     unsigned long long c(1);
  67.     // Perform the product over the space i = [1...k]
  68.     for( int i = 1; i < k+1; i++ )
  69.     {
  70.         c *= n - (k - i);
  71.         c /= i;
  72.     }
  73.  
  74.     return c;
  75.  
  76. }
  77.  
  78. //====================================================
  79. // Purpose: How many more combinations have we got
  80. //      left?
  81. //====================================================
  82. unsigned long long CombinationGenerator::GetNumLeft()
  83. {
  84.     return m_iNumLeft;
  85. }
  86.  
  87. //====================================================
  88. // Purpose: Have we finished creating combinations?
  89. //====================================================
  90. bool CombinationGenerator::IsFinished()
  91. {
  92.     return( m_iNumLeft == 0 );
  93. }
  94.  
  95. //====================================================
  96. // Purpose: Compute our next combination:
  97. //====================================================
  98. std::vector<int> CombinationGenerator::NextCombination()
  99. {
  100.     // If this is the first combination, return the original
  101.     // vector:
  102.     if( m_iNumLeft == m_iNumCombinations )
  103.     {
  104.         m_iNumLeft -= 1;
  105.         return m_vecCurrCombination;
  106.     }
  107.  
  108.     int i = k - 1;
  109.     while( m_vecCurrCombination[i] == n - k + i )
  110.     {
  111.         i--;
  112.     }
  113.  
  114.     m_vecCurrCombination[i] += 1;
  115.  
  116.     for( int j = i; j < k; j++ )
  117.     {
  118.         m_vecCurrCombination[j] = m_vecCurrCombination[i] + j - i;
  119.     }
  120.  
  121.     m_iNumLeft -= 1;
  122.  
  123.     return m_vecCurrCombination;
  124.  
  125. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement