1

私は遺伝的アルゴリズムプログラムを書いています。Linux (OS)、c++ (言語)、g++ (コンパイラ) を使用しています。次のコードは、セグ フォールトを生成します。問題は、50 回以上実行されることもあれば、まったく実行されないこともあります。さらに、エラーは tmp[ k ][ p ] または tmp[ k + 1 ][ p ] 割り当て行のいずれかで発生します。ここで何か不足していますか?

int** GeneticAlgorythm::newGeneration( int** parents )
{
    int** tmp = new int*[ population ];
    int p = 0;

    for( int k = 0; k < population; k += 2 )
    {
        tmp[ k ] = new int[ nGenes ];
        tmp[ k + 1 ] = new int[ nGenes ];
        setLikelihood( parents );

        int parent1 = getParent( likelyhood );
        int parent2 = getParent( likelyhood );

        while( parent1 == parent2 )
        {
            parent2 = getParent( likelyhood );
        }

        for( p = 0; p < crossOverPoint; p++ )
        {
            tmp[ k ][ p ] = parents[ parent1 ][ p ];
            tmp[ k + 1 ][ p ] = parents[ parent2 ][ p ];
        }

        for( p = crossOverPoint; p < nGenes; p++ )
        {
            tmp[ k ][ p ] = parents[ parent2 ][ p ];
            tmp[ k + 1 ][ p ] = parents[ parent1 ][ p ];
        }
    }

    currGeneration++;
    return tmp;
}


int GeneticAlgorythm::getParent( double* lh )
{
    int randVal = rand( ) % 100;
    int* choose = new int[ 100 ];
    int counter = 0;

    for( int k = 0; k < population; k++ )
    {
        for( int j = 0; j < (int)likelyhood[ k ]; j++ )
        {
            choose[ counter++ ] = j;
        }
    }

    counter = choose[ randVal ];
    delete[] choose;
    return counter;
}

void GeneticAlgorythm::setLikelihood( int** pg )
{
    multipleInverse = 0;
    double one = 1.00;

    for( int mi = 0; mi < population; mi++ )
    {
        multipleInverse  += one/checkFitness( pg[ mi ] );

    }

    for( int lh = 0; lh < population; lh++ )
    {
        likelyhood[ lh ] = round(((one/checkFitness( pg[ lh ] ))/multipleInverse) * 100);
    }

}

変数値: 人口 = 20; n遺伝子 = 3; クロスオーバーポイント = 1;

可能性は、フィットネスレベルに基づいて親が選択される可能性です。pg は親遺伝子です。[人口][nGenes]。

前もって感謝します。

4

3 に答える 3

3

指定した値を見ると、インデックス付けtmpは問題ないようです。セグメンテーション違反が発生している行が

tmp[ k ][ p ] = parents[ parent1 ][ p ];
tmp[ k + 1 ][ p ] = parents[ parent2 ][ p ];

parentswithへのインデックス付けが原因である必要があり[ parentN ][ p ]ます。の寸法はparents? getParent(…)に有効なインデックスを返すことが保証されていparentsますか?

于 2013-05-02T21:05:48.603 に答える
2

あなたtmp[k+1]は限界を超えることができます。= 3と仮定populationします。2 番目のループ実行ではi=2、tmp[3] が実行されます。tmp[i+1]これは範囲外であり、バッファ領域外のメモリを変更しているため、未定義の動作を引き起こす可能性があります。

populationそれが常に偶数であると確信していない限り。

于 2013-05-02T20:59:13.503 に答える
2

このコードでは:

int** tmp = new int* [population];

for (int k = 0; k < population; k += 2)
{
    tmp[k] = new int[nGenes];
    tmp[k + 1] = new int[nGenes];
    ...
}

populationが奇数の場合tmp[k + 1]、最後の反復内でその範囲外の配列にアクセスすると、未定義の動作が発生します。セグメンテーション違反によるプログラムのクラッシュを観察できたのは幸運でした。そうでなければ、このバグは隠れていた可能性があります。

于 2013-05-02T21:04:05.987 に答える