2

関数の 1 つで、予期しない問題が発生しました。説明させてください。キャリブレーション アルゴリズムを作成しています。グリッド検索 (非連続最適化) を実行したいので、独自のメッシュ (確率のさまざまな組み合わせ) を作成しています。グリッドのサイズとグリッド自体は再帰的に計算されます (私は知っています...)。順番に:

  1. 変数を取得する
  2. 対応するサイズを再帰的に計算する
  3. グリッドにメモリを割り当てる
  4. 参照によって空のグリッドを渡し、再帰的に埋める

私が抱えている問題は、このグリッドを取得しようとした後、ステップ 4 の後です。ステップ 4 で、コンソールに結果を「出力」して確認しました、問題はありませんでした。いくつかの変数を使用していくつかのグリッドを計算しましたが、それらはすべて期待した結果と一致しています。ただし、グリッドが再帰関数から取り出されるとすぐに、最後の列は 0 で埋められます (以前のすべての値は、この列でのみ置き換えられます)。手順 3 でグリッドに追加の列を 1 つ割り当てようとしましたが、これは問題を悪化させるだけでした (-3e303 などの値)。また、計算するサイズ(非常に小さいものから非常に大きいものまで)に関係なくエラーが発生するため、メモリエラー(または少なくとも「メモリ不足」エラー)ではないと想定しています。最後に、使用される 2 つの関数とその呼び出しを以下に示します。これはすぐにプログラムされたので、一部の変数は役に立たないように見えるかもしれません。ただし、私はいつでもあなたのコメントを受け付けています (さらに、私は 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」を残しました。それらは問題を絞り込むのに役立ちます。ほとんどの場合、1 つのメモリ割り当てを忘れたか、取り壊した可能性があります。でもどっちか分からない。とにかく、助けてくれてありがとう!

4

1 に答える 1

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]) {
 ...
}

きれいで読みやすいコードができたら、バグを簡単に見つけることができます。

于 2013-01-22T21:44:47.073 に答える