我的一个功能有一个相当意外的问题。让我解释。 我正在编写校准算法,因为我想做一些网格搜索(非连续优化),我正在创建自己的网格 - 不同的概率组合。 网格的大小和网格本身的计算是递归(我知道......)。 所以按顺序:
我遇到的问题是在尝试检索此网格后的第4步之后。在第4步中,我在控制台上“打印”结果以检查它们,并且一切都可以。我用几个变量计算了几个网格,它们都符合我期望的结果。但是,一旦网格从递归函数中取出, last 列将填充0(之前的所有值仅在此列中替换)。 我尝试在步骤3中为网格分配一个额外的列,但这只会使问题变得更糟(-3e303等值)。我也有错误,无论我用它计算它的大小(非常小到非常大),所以我认为它不是内存错误(或者至少是'缺少内存'错误)。最后使用的两个函数和它们的调用已在下面列出,这已被快速编程,因此一些变量似乎没用 - 我知道。但是我总是对你的意见持开放态度(加上我不是C ++的专家 - 因此这个主题)。
void size_Grid_Computation(int nVars, int endPoint, int consideredVariable, int * indexes, int &sum, int nChoices)
{
/** Remember to initialize r at 1 !! - we exclude var_0 and var_(m-1) (first and last variables) in this algorithm **/
int endPoint2 = 0;
if (consideredVariable < nVars - 2)
{
for (indexes[consideredVariable] = 0; indexes[consideredVariable] < endPoint; indexes[consideredVariable] ++)
{
endPoint2 = endPoint - indexes[consideredVariable];
size_Grid_Computation(nVars, endPoint2, consideredVariable + 1, indexes, sum, nChoices);
}
}
else
{
for (int i = 0; i < nVars - 2; i++)
{
sum -= indexes[i];
}
sum += nChoices;
return;
}
}
以上功能适用于网格尺寸。下面是网格本身 -
void grid_Creation(double* choicesVector, double** varVector, int consideredVariable, int * indexes, int endPoint, int nVars, int &r)
{
if (consideredVariable > nVars-1)
return;
for (indexes[consideredVariable] = 0; indexes[consideredVariable] < endPoint; indexes[consideredVariable]++)
{
if (consideredVariable == nVars - 1)
{
double sum = 0.0;
for (int j = 0; j <= consideredVariable; j++)
{
varVector[r][j] = choicesVector[indexes[j]];
sum += varVector[r][j];
printf("%lf\t", varVector[r][j]);
}
varVector[r][nVars - 1] = 1 - sum;
printf("%lf row %d\n", varVector[r][nVars - 1],r+1);
r += 1;
}
grid_Creation(choicesVector, varVector, consideredVariable + 1, indexes, endPoint - indexes[consideredVariable], nVars, r);
}
}
最后通话
#include <stdio.h>
#include <stdlib.h>
int main()
{
int nVars = 5;
int gridPrecision = 3;
int sum1 = 0;
int r = 0;
int size = 0;
int * index, * indexes;
index = (int *) calloc(nVars - 1, sizeof(int));
indexes = (int *) calloc(nVars, sizeof(int));
for (index[0] = 0; index[0] < gridPrecision + 1; index[0] ++)
{
size_Grid_Computation(nVars, gridPrecision + 1 - index[0], 1, index, size, gridPrecision + 1);
}
double * Y;
Y = (double *) calloc(gridPrecision + 1, sizeof(double));
for (int i = 0; i <= gridPrecision; i++)
{
Y[i] = (double) i/ (double) gridPrecision;
}
double ** varVector;
varVector = (double **) calloc(size, sizeof(double *));
for (int i = 0; i < size; i++)
{
varVector[i] = (double *) calloc(nVars, sizeof(double *));
}
grid_Creation(Y, varVector, 0, indexes, gridPrecision + 1, nVars - 1, r);
for (int i = 0; i < size; i++)
{
printf("%lf\n", varVector[i][nVars - 1]);
}
}
我离开了我的野蛮人'printf',他们帮助缩小了问题的范围。最有可能的是,我已经忘记或屠杀了一个内存分配。但我看不出哪一个。无论如何,谢谢你的帮助!
答案 0 :(得分:1)
在我看来,你有一个主要的错误设计,即你的2D阵列。你在这里编程的是不是 2D数组,而是它的模拟。只有你想要一种稀疏的数据结构才能省略部分才有意义。在你的情况下,它看起来好像只是一个你需要的普通旧矩阵。
现在,在C和C ++中都不适合这样编程。
在C中,因为这看起来就是你所追求的内部函数,你甚至用动态边界声明矩阵
double A[n][m];
如果你担心这会粉碎你的“堆叠”,你可以动态分配它
double (*B)[m] = malloc(sizeof(double[n][m]));
通过将边界首先放在参数列表
中,将这些野兽传递给函数void toto(size_t n, size_t m, double X[n][m]) {
...
}
一旦你有清晰易读的代码,你就会发现你的错误更容易。