1

我正在编写一个遗传算法程序。我使用 Linux(操作系统)、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;nGenes = 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]可以越界。假设population= 3。在您的第二次循环运行中,您得到了i=2并且您执行tmp[i+1]的是 tmp[3] 并且超出了界限,这可能导致未定义的行为,因为您正在修改缓冲区空间之外的内存。

除非你确定它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 回答