I have an algorithm which generates combinations from entries of a container and I want to find the combination which minimizes a cost function:
struct Vec { double x; double y; };
double cost( Vec a, Vec b ) {
double dx = a.x - b.x;
double dy = a.y - b.y;
return dx*dx + dy*dy;
}
pair<Vec,Vec> get_pair_with_minimum_cost ( vector<Vec> inp, double (*cost_fun)(Vec,Vec) )
{
pair<Vec,Vec> result;
double min_cost = FLT_MAX;
size_t sz = inp.size();
for(size_t i=0; i<sz; i++) {
for (size_t j=i; j<sz; j++) {
double cost = cost_fun(inp[i], inp[j]);
if (cost < min_cost) {
min_cost = cost;
result = make_pair(inp[i], inp[j]);
}
}
}
return result;
}
vector <Vec> inp = {....};
auto best_pair = get_pair_with_minimum_cost ( inp, cost );
Unfortunately, get_pair_with_minimum_cost() does 2 jobs:
- generates the combinations
- gets the minimum element
I could break them in two functions, like:
- the generator:
template <class Func> void generate_all_combinations_of( vector<Vec> inp, Func fun ) { size_t sz = inp.size(); for(size_t i=0; i<sz; i++) { for (size_t j=i; j<sz; j++) { fun(make_pair(inp[i], inp[j])); } } } - and then use
std::min_elementon the output of the generator, i.e.vector<Vec> inp = {....}; vector<pair<Vec,Vec>> all_combinations; generate_all_combinations_of(inp, [&](vector<pair<Vec,Vec>> o){all_combinations.push_back(o); } ); auto best_pair = *min_element(all_combinations.begin(), all_combinations.end(), cost);
but I do not want the pay the cost of creating and extra container with temporary data (all_combinations).
Questions:
Can I rewrite the
generate_all_combinations_of()such that it usesyieldor the newstd::rangesin such a way that I can combine it with STL algorithms such asfind_if,any_of,min_elementor evenadjacent_pair?
The great thing about this 'generator' function is that it is easy to read, so I would like to keep it as readable as possible.
NB: some of these algorithms need tobreakthe loop.What is the official name of combining entries this way? It this the combinations used in 'bubble-sort'.