我正在写一个遗传算法程序。我使用Linux(OS),c ++(语言)和g ++(编译器)。 以下代码生成seg错误。问题是它有时会运行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; crossOverPoint = 1;
可能性是根据父母的健康水平选择父母的可能性。 pg是亲本基因。 [人口] [nGenes]。
提前致谢。
答案 0 :(得分:3)
查看您提供的值,看起来您对tmp
的索引是正常的。如果您看到段错误的行是
tmp[ k ][ p ] = parents[ parent1 ][ p ];
tmp[ k + 1 ][ p ] = parents[ parent2 ][ p ];
它必须是因为parents
与[ parentN ][ p ]
的索引。
parents
的维度是多少? getParent(…)
是否保证将有效索引返回parents
?
答案 1 :(得分:2)
你的tmp[k+1]
可能超出范围。假设population
= 3.在你的第二次循环运行中你得到了i=2
而你做了tmp[i+1]
这是tmp [3]并且超出界限会导致未定义的行为,因为你是修改缓冲区空间之外的内存。
除非您确定population
总是是偶数。
答案 2 :(得分: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]
会从其边界中访问数组,从而产生 未定义的行为 。您很幸运能够观察到由于分段错误而导致程序崩溃,否则此错误可能会隐藏起来。