使用C生成所有元组 - 比嵌套循环更好的方法?

lum*_*ric 2 c loops nested-loops

我有一个double x[]长度为11 的数组和一个函数f(double x[]).我想f()通过离散化找到函数的最小值.所以对于给定的值,val1, val2, ..., valn我需要一个循环通过{val_1,...,val_n} ^ 11中的x的所有元组.我可以很容易地使用11个嵌套循环,但这真的是我能做的最有效吗?

编辑: 澄清事情:函数f()在11维集上定义.我想评估一个11维网格的顶点上的函数.对于网格的尺寸h,为所述阵列的条目可能值x[]可以是0,h,2*h,...,n*h= val_1,val_2,...,val_n.因此,在开始时f(val_1, val_1, ..., val_1)应该评估,然后f(val_1, val_1, ...,val_1, val_2),...和在和 f(val_n, val_n, ..., val_n).我实际上并不关心顺序,但我确实关心速度,因为有很多这样的元组.确切地说,有n ^ 11个这样的元组.因此,对于n = 10 f(),必须评估10 ^ 11次.我的计算机f()每秒可以评估大约5*10 ^ 6次,因此对于n = 10,评估f() 需要5个小时.这就是为什么我在寻找最有效的方法来实现它.

Oli*_*rth 6

这是伪代码(不一定是语法正确的C代码),用于迭代所有可能元组的非递归方法:

const int vals[]        = { val1, val2, val3, ... };

int       x[NUM_DIMS]   = { vals[0], vals[0], ... };  // The current tuple
int       i[NUM_DIMS]   = { 0 };                      // Index of each element in x[]


while (1)
{
    f(x);  // Whatever

    // Update x (we increment i[] treated as a base-N number)
    int j;
    for (j = 0; j < NUM_DIMS; j++)
    {
        i[j]++;                          // Increment the current digit
        x[j] = vals[i[j]];               // Update (via mapping)
        if (i[j] < NUM_VALS) { break; }  // Has this digit wrapped?
        // We've caused a carry to the next digit position
        i[j] = 0;                        // Wrap
        x[j] = vals[0];                  // Update (via mapping)
    }
    if (j == NUM_DIMS) { break; }  // All digits wrapped, therefore game over
}
Run Code Online (Sandbox Code Playgroud)