我正在寻找一种高速解决方案,通过启动步骤停止方案来循环具有不同变量的所有组合的功能。 仅在运行时才知道哪些变量被激活用于组合。 (use = false / true)。
可能的解决方案可以使用递归或反向跟踪,但对于应用程序来说太慢了。
对我而言,挑战是:
解决方案怎么样?
在此示例中,所有活动变量的可能组合为10 * 11 * 21 = 2310 实际上有更多的变量和更多可能的组合,可能高达数百万(需要高性能解决方案的原因)。
int i1_use = true;
int i1_value = 1; // the normal value that the function use
int i1_start_value = 1;
int i1_step_value = 2;
int i1_stop_value = 20;
// 1,3,5,7,9,11,13,15,17,19
// -> gives 10 different values
int i2_use = false;
int i2_value = 100; // the normal value that the function use
int i2_start_value = 1000;
int i2_step_value = 500;
int i2_stop_value = 3000;
// -> use = false! no combination!
double d1_use = true;
double d1_value = 1.234; // the normal value that the function use
double d1_start_value = 0;
double d1_step_value = 0.02;
double d1_stop_value = 0.2;
// 0,0.02,0.04,0.06,0.08,0.1,0.12,0.14,0.16,0.18,0.2
// -> gives 11 different values
double d2_use = true;
double d2_value = 10; // the normal value that the function use
double d2_start_value = 10;
double d2_step_value = 0.5;
double d2_stop_value = 20;
// 10,10.5,11,11.5,12,12.5,13,13.5,14,14.5,15,15.5,16,16.5,17,17.5,18,18.5,19,19.5,20
// -> gives 21 different values
// All combinations 10*11*21 = 2310
答案 0 :(得分:0)
首先,将变量组合成结构是合理的。但假设代码的其余部分保持原样,我建议不管怎样创建一个辅助构造:
// an interface to use in vector
class CombinatorInterface {
public:
virtual bool nextValue() = 0;
};
// and template implementation for different types (int, float, etc.)
template <typename T>
class Combinator: public CombinatorInterface {
public:
Combinator(bool inUse, T currentValue, T startValue, T stepValue, T stopValue) :
_inUse{inUse},
_currentValue{currentValue},
_startValue{startValue},
_stepValue{stepValue},
_stopValue{stopValue}
{}
// Now this is overly simplified, as you might need better error checks and maybe different approaches for integral and float types
bool nextValue() override {
if (_inUse == false) {
return false;
}
if (_currentValue < _stopValue) {
_currentValue += _stepValue;
return true;
} else {
return false;
}
}
private:
bool& _inUse;
T& _currentValue;
T& _startValue;
T& _stepValue;
T& _stopValue;
};
然后您可以在以下代码中使用此构造:
std::vector<CombinatorInterface*> v;
v.push_back(new Combinator<int>(i1_use , i1_value, i1_start_value, i1_step_value , i1_stop_value));
// more like this
v.push_back(new Combinator<double>(d2_use, d2_value, d2_start, d2_step_value, d2_stop_value));
bool permutationAvailable = true;
do {
permutationAvailable = false;
for (auto i: v) {
if (i->nextValue()) {
permutationAvailable = true;
break;
}
// do your measurements for every iteration
}
} while(permutationAvailable);
// do the part after there are no more iterations
现在这将使用address_size * parameters * 5
内存,如果你只使用一组变量就可以消除,即在整个代码中使用相同的向量。
另一个开销是多态基,这将导致每个nextValue()
调用的额外地址查找。否则这将是一个简单的暴力迭代。