For some algorithm I have to call a function f
on all permutations of the n
-element set of integers
ranging from 1 to n. Finally, I am interested in the 100 permutations yielding the smallest f
-value.
The best solution I was able to work out was the following one. But it has a serious drawback. While n
increases fPerm
can consume a large amount of memory.
What is the best solution to trim fPerm
, so that it keeps only the best 100 solutions found so far?
#include <vector>
#include <set>
#include <algorithm>
#include <numeric>
#include <boost/random.hpp>
boost::random::mt19937 rng;
// Actually, f is a very complex function, that I'm not posting here.
double f(const std::vector<int>& perm) {
boost::random::uniform_real_distribution<> gen;
return gen(rng);
}
typedef std::pair<std::vector<int>, double> TValue;
void main(int argc, int args) {
auto comp = [](const TValue& v1, const TValue& v2) { return v1.second < v2.second; };
std::set<TValue, decltype(comp) > fPerm(comp);
int n = 7;
std::vector<int> perm(n);
std::iota(perm.begin(), perm.end(),1);
do {
fPerm.insert(TValue(perm, f(perm)));
} while (std::next_permutation(perm.begin(), perm.end()));
// Get first smallest 100 values, if there are such many.
int m = 100 < fPerm.size() ? 100 : fPerm.size();
auto iterEnd = fPerm.begin();
std::advance(iterEnd, m);
for (auto iter = fPerm.begin(); iter != iterEnd; iter++) {
std::cout << iter->second << std::endl;
}
}