我试图在 C++ 中实现遗传算法。我把它和我之前的BP网络项目结合起来,然后问题就来了。当我尝试向它提供一些复杂的数据时,会弹出 ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)) 错误。
下面是我这部分的主体
float NeuralNetwork::Optimize()
{
TotalFitness = 0;
std::list<SPopulation>::iterator Data;
if( Population.size() == 0)
Population = InitializePopulation();
for( Data = Population.begin(); Data!=Population.end(); ++Data )
{
Clean((*Data).Data.y);
(*Data).Data.y = Predict( (*Data).Data.x );
SVector Expected = GetTruth( (*Data).Data.x );
float Temp = 0;
for( int i=0; i<Expected.Size; i++ )
{
Temp += powf( Expected.Data[i] - (*Data).Data.y.Data[i], 2 );
}
Clean( Expected );
(*Data).Fitness = Temp/2;
TotalFitness += (*Data).Fitness;
(*Data).Fitness = 1 / (1+(*Data).Fitness);
}
TotalFitness /= Population.size();
TotalFitness = 1 / (1+TotalFitness);
Select();
Cross();
Mutate();
return TotalFitness;
}
std::list Population 是我的 Network 类的私有成员。通常在我训练它 4 或 5 次后,它会在第一个 Clean 功能时崩溃。
void NeuralNetwork::Clean( SVector& x )
{
if( (x.Size != 0) && (x.Data != NULL) )
{
//cout<<"Delete pointer at address :"<<hex<<x.Data<<endl;
delete[] x.Data;
x.Size = 0;
x.Data = NULL;
}
}
void NeuralNetwork::Clean( SData& x )
{
Clean( x.x );
Clean( x.y );
}
然后真正奇怪的事情发生了,当我删除 Mutate() 函数时,一切正常。但是 Mutate 函数中没有任何东西会导致这个问题。
void NeuralNetwork::Mutate( )
{
srand((unsigned)time(NULL));
double x;
double PMutation = 0.20;
if( Population.size() == 0 )
return;
std::list<SPopulation>::iterator It;
for( It = Population.begin(); It!=Population.end(); ++It )
{
for( int i=0; i<mCreateInfo.InputNodes; i++ )
{
x = rand()%1000/1000.0;
if (x < PMutation)
{
SVector S = (*It).Data.x;
float NewValue = (((float)(rand()%1000)/1000.0)*(mBoundHigh - mBoundLow) + mBoundLow);
S.Data[0] = NewValue;
}
}
}
}
在我的测试中,mCreateInfo.InputNodes 始终为 0。我开始思考可能导致问题的原因。然后我意识到只有在 Select() 函数中我从 Population 列表中删除了一些实体。但这也不是问题。因为如果我删除 Select 函数和 Cross() 函数只留下 Mutate() ,它仍然会崩溃。
我真的不知道现在可能导致错误的原因。
ps:
现在它有时也会在这里崩溃。这是令人难以置信。得到 Expected 对象后,直接清理还是会报错。它不能尝试两次删除指针。
SVector Expected = GetTruth( (*Data).Data.x );
float Temp = 0;
for( int i=0; i<Expected.Size; i++ )
{
Temp += powf( Expected.Data[i] - (*Data).Data.y.Data[i], 2 );
}
Clean( Expected );