#include #include #include #include "Histogram.h" #include "Util.h" HistogramSet::HistogramSet (unsigned size, unsigned range) { size_ = size; hist_.resize (range, 0); hist_[0] = size; } void HistogramSet::nextHistogram (void) { for (int i = hist_.size() - 2; i >= 0; i--) { if (hist_[i] > 0) { hist_[i] --; hist_[i + 1] = maxCount (i + 1); clearAfter (i + 1); break; } } assert (std::accumulate (hist_.begin(), hist_.end(), 0) == (int)size_); } unsigned HistogramSet::operator[] (unsigned idx) const { assert (idx < hist_.size()); return hist_[idx]; } unsigned HistogramSet::nrHistograms (void) const { return Util::nrCombinations (size_ + hist_.size() - 1, hist_.size() - 1); } void HistogramSet::reset (void) { std::fill (hist_.begin() + 1, hist_.end(), 0); hist_[0] = size_; } vector HistogramSet::getHistograms (unsigned N, unsigned R) { HistogramSet hs (N, R); unsigned H = hs.nrHistograms(); vector histograms; histograms.reserve (H); for (unsigned i = 0; i < H; i++) { histograms.push_back (hs.hist_); hs.nextHistogram(); } return histograms; } unsigned HistogramSet::nrHistograms (unsigned N, unsigned R) { return Util::nrCombinations (N + R - 1, R - 1); } unsigned HistogramSet::findIndex ( const Histogram& hist, const vector& histograms) { vector::const_iterator it = std::lower_bound ( histograms.begin(), histograms.end(), hist, std::greater()); assert (it != histograms.end() && *it == hist); return std::distance (histograms.begin(), it); } ostream& operator<< (ostream &os, const HistogramSet& hs) { os << "#" << hs.hist_; return os; } unsigned HistogramSet::maxCount (unsigned idx) const { unsigned sum = 0; for (unsigned i = 0; i < idx; i++) { sum += hist_[i]; } return size_ - sum; } void HistogramSet::clearAfter (unsigned idx) { std::fill (hist_.begin() + idx + 1, hist_.end(), 0); }