1

私は研究タスクのために遺伝的アルゴリズムをプログラミングしています。私は経験豊富な C++ プログラマーではありませんが (数学者であるため)、Windows 環境で MSVC 2008 と g++ コンパイラを使用して正しくコンパイルおよび実行されるようにプログラムを管理しました (CygWin を使用して Windows 7 で g++ を実行しました)。問題は、このプログラムを Linux 環境で g++ を使用するクラスター コンピューターで実行する必要があることですが、実行時に常にクラッシュします (少なくとも正しくコンパイルされます)。明らかな詳細 (ファイル名に \ の代わりに / を使用するなど) に対処しましたが、Linux で適切に実行することはできませんでした。

ただし、以下の関数「Cruce」にコメントすると、プログラムは終了しますが、明らかに必要なタスクは実行されません。これは、そのような関数のコードと、それによって呼び出される他の関数です (唯一のグローバル変数は BITGEN で、浮動小数点数のグレイ コード変換に使用される値 30 の整数です)。

    void xPC_BLX(double d, const vector<double>& P1, const vector<double>& P2,
    vector<double>& Hijo1, vector<double>& Hijo2, int genes){

    double I, A1, C1;
    int i;

    for (i=0; i < genes; i++)
    {

        I= d * fabs(P1[i]-P2[i]);

        A1=P1[i]-I; if (A1<0) A1=0.0;
        C1=P1[i]+I; if (C1>1) C1=1.0;
        Hijo1[i]= A1 + Rand()*(C1-A1);

        A1=P2[i]-I; if (A1<0) A1=0.0;
        C1=P2[i]+I; if (C1>1) C1=1.0;
        Hijo2[i]= A1 + Rand()*(C1-A1);
        }
    }

/**********************************************************/
/* Itoc and Ctoi translate ints to strings and vice versa */
/**********************************************************/
    unsigned long int Ctoi(char *Cad_ent,  int length){

        int i;      
    unsigned long n;    

    n = (unsigned long) 0;
    for (i=0; i<length; i++)
    {
        n <<= 1;
        n += (*Cad_ent++ - (int) '0');
    }
    return(n);
    }

    void Itoc(unsigned long int n, char *Cad_sal, int length){

        int i;      

        for (i=length-1; i>=0; i--)
        {
            Cad_sal[i] = (char)('0' + (n & 1));
            n >>= 1;
        }
    }


/*****************************************************************/
/* Translations between fixed point ints and reflected Gray code */
/*****************************************************************/

    void Gray(char *Cad_ent, char *Cad_sal, int length){

      int i;
      char last;

       last = '0';
       for (i=0; i<length; i++)
       {
        Cad_sal[i] = (char)('0' + (Cad_ent[i] != last));
        last = Cad_ent[i];
       }
    }

/*************************************************************************/
/* Translations between string representation and floating point vectors */
/*************************************************************************/
    void StringRep(const vector<double> vect, char *Cad_sal, int genes){

        int i;
        unsigned long int n;
        int pos;
        double INCREMENTO;
        static char *tmpstring;
        static int flag = 1;

        if (flag) {
        tmpstring = (char*) calloc (genes*BITGEN,sizeof(char));
        flag = 0;
        }

        pos = 0;
        for (i=0; i < genes; i++)
        {

        INCREMENTO=(1-0)/(pow(2.0, (double) BITGEN) - 1.0);

        n = (int) ((vect[i] - 0) / INCREMENTO + 0.5);

        Itoc(n, tmpstring, BITGEN);
        Gray(tmpstring, &Cad_sal[pos], BITGEN);

        pos += BITGEN;
        }
        Cad_sal[pos] = '\0';

    }

/*****************************************/
    int DistHam(char *Cr_1, char *Cr_2, int genes){

         int i, dist;
         dist=0;

         for (i=0; i<genes*BITGEN; i++) if (Cr_1[i]!=Cr_2[i]) dist++;

         return dist ;
    }

/**********************/
/* CROSS OPERATOR  */
/**********************/

    void Cruce(int& fin, int genes, vector<vector<double> >& POPULATION,
        vector<vector<double> >& CONTROL, double GA_THR)
    {

        int i, j, temp, mom, dad;
        static char *String1, *String2;
        static int flag=1;
        vector<double> newind(genes+1,0), newcont(2,0);


        if (flag) {
        String1 = (char*) calloc (genes*BITGEN,sizeof(char));
        String2 = (char*) calloc (genes*BITGEN,sizeof(char));
        flag = 0;
        }

        vector<int> sample(TAMPOP,0);  
        for (i=0; i < TAMPOP; i++) sample[i] = i;

    for (i=0; i < TAMPOP; i++)
    {
        j = Randint(i,TAMPOP-1);
        temp = sample[j];
        sample[j] = sample[i];
        sample[i] = temp;
    }

    for (i=0; i < TAMPOP; i++) CONTROL[i][0]=0;

    fin=TAMPOP;

    for (i=0; i < TAMPOP/2; i++)
    {
        mom=sample[2*i]; 
        dad=sample[2*i+1];


        StringRep(POPULATION[mom], String1, genes);
        StringRep(POPULATION[dad], String2, genes);


        if (DistHam(String1, String2, genes)/2.0 > GA_THR)
        {

            POPULATION.push_back(newind);

            POPULATION.push_back(newind);

            CONTROL.push_back(newcont);

            CONTROL.push_back(newcont);

            xPC_BLX(1,POPULATION[mom],POPULATION[dad],POPULATION[fin],   
                POPULATION[fin+1], genes);

            CONTROL[fin][0]=1;
            CONTROL[fin+1][0]=1;
            fin=fin+2;  

        }
    }
}

考えられるエラーを見つけるために何日も最善を尽くしましたが、無駄でした. エラーはメモリの問題に関連している必要があると思いますが(常にセグメンテーション違反エラーが発生するため)、どこにあるのかわかりませんでした。私が認識していない Windows と Linux のメモリ処理方法には重大な違いがあるはずです。どなたか助けていただけませんか?

前もって感謝します!

4

2 に答える 2

2

あなたを助けるかもしれないいくつかの一般的なヒント:

  • -Wall -Wextraオプションを使用してコンパイルし、g++すべての警告がなくなるまでソース コードを改善します。

  • また、 (または同様の)オプションを使用してclang ++コンパイラでコンパイルしてみてください-Wall

  • -g( に加えて) オプションを指定してコンパイルし、-Wallデバッグ情報を取得します。

  • gdbを使用してプログラムをデバッグします (デバッガーでプログラムを実行し、btバックトレースなどに使用します...)

  • valgrindを使用してメモリ リークを見つける

  • callocと の使用を避けmalloc、標準の C++ コンテナー ( 、 など) を使用するstd::stringことをstd::vector<>お勧めします。std::map<>

また、自分のラップトップまたはデスクトップに Linux ディストリビューションをインストールし、コマンド ラインから Linux を使用する方法を学びます。

于 2012-10-21T13:23:20.990 に答える
2

提示されたコードにエラーの可能性があります。

    static char *tmpstring;
    static int flag = 1;

    if (flag) {
        tmpstring = (char*) calloc (genes*BITGEN,sizeof(char));
        flag = 0;
    }

増加する引数で関数StringRep()が複数回呼び出された場合に何が起こるかgenes: バッファは増加しないため、割り当てられた最初のバッファの外に誰かが書き込もうとしています。function にも同じことが当てはまることに注意してくださいCruce()

次に、 に関する 2 番目のエラーがあると思いますfin=TAMPOP;。とは何かについての説明はありませんTAMOPPOPULATION[fin+1]しかし、またはを行うときに配列の外に出ていませんCONTROL[fin+1][0]=1;fin=fin+2;

よろしく。

于 2012-10-21T13:40:57.470 に答える