关于遗传算法的函数优化应用方面问题,出现了内存溢出,没找到哪里错误
参考的代码地址为http://blog.csdn.net/ebowtang/article/details/50938396
很多人应该是看这个代码入门遗传算法的
自己的运行代码如下
头文件
#include<vector>
#include "math.h"
#include "string.h"//不知道为什么要加这个,明明模板没加也没错,这边不加就会报错unexpected token(s) preceding ';'
using namespace std;
const double pi=3.1415926;
class Genome
{
public:
friend class GenAlg; //种群全部基因
friend class GenEngine;
Genome() /*没加这个花括号的话会有
function operation.obj : error LNK2001:
unresolved external symbol "public: __thiscall Genome::Genome(void)" (??0Genome@@QAE@XZ)提示*/
{
}
Genome(vector<double> vec , double f)
{
vecGenome=vec;
fitness=f;
}
~Genome()
{}
private:
vector<double> vecGenome; //在求函数最优单解时,定义基因组至于要double 就行了,用vector是为了扩展以后会碰到的情况
double fitness;
};
class GenAlg
{
public:
vector<Genome> vecPop; //整个种群的基因组
int popsize; //种群的个数
int Genomelength;//一个基因组中基因的总数目,每条染色体上基因的总数目
double totalfitness;
double bestfitness;
double averagefitness;
double worstfitness;
Genome bestone;
double maxperturtation;//最大的变异步长
double leftpoint,rightpoint;//左右值域
double mutationrate;//这个为基因突变的概率
double crossoverRate;//基因交叉的概率
GenAlg();//不明白为什么要设置这个初始化函数
void Reset();//暂时也不知道拿来干嘛用
void init(int popSize,double MutRate,double CrossRate,int GenLenght,
double LeftPoint,double RightPoint);
void report(int numgen);
void Calculatebestworstavetol();
Genome GetGenomeRoulette();//轮盘赌算法
void Mutate(vector<double> &chrome);//基因突变函数
void Epoch(vector<Genome> &vecNewPop);
~GenAlg()
{}
};
class Curve
{
public:
double function(vector<double> input)//这里不用引用与常量符号应该也没事吧
{
double x=input[0];
double output=0;
output=x*sin(10*pi*x)+2.0;
return output;
}
~Curve()
{}
private:
};
class GenEngine
{
public:
GenEngine(int popSize,double MutRate,double CrossRate,int GenLenght,int Generation,
double LeftPoint,double RightPoint);//这里的形参与GenAlg.init里的一样,尝试
void OnStartGenAlg();
~GenEngine()
{}
private:
GenAlg genAlg;
//这里特意不包含Curve的变量以测试在不包含相应类的变量情况下是否能使用类的函数,看来似乎不行
Curve curve;
vector<Genome> g_population; //新的种群基因库
int g_popSize;
double g_MutRate;
double g_CrossRate;
int g_GenLenght;
int g_Generation;
int numgeneration;//迭代的计数器
double g_LeftPoint;
double g_RightPoint;
};
操作文件
#include<vector>
#include<stdio.h>
#include <stdlib.h>
#include <time.h>
#include<iostream>
#include"class.h"
using namespace std;
double random()
{
double randNum;
randNum=rand()*1.0/RAND_MAX;
return randNum;
}
void GenAlg::init(int popSize,double MutRate,double CrossRate,int GenLenght,
double LeftPoint,double RightPoint)
{
popsize=popSize;
Genomelength=GenLenght;
totalfitness=0;
bestfitness=0;
averagefitness=0;
worstfitness=999;
maxperturtation=0.004;
leftpoint=LeftPoint;
rightpoint=RightPoint;
mutationrate=MutRate;//这个为基因突变的概率
crossoverRate=CrossRate;
vecPop.clear();
//这里要加上初始化种群基因库的部分
for(int i=0;i<popsize;i++)
{
vecPop.push_back(Genome());//不能用 vecPop[i].push_back(Genome());
for(int j=0;j<Genomelength;j++)
{
vecPop[i].vecGenome[j]=random()*(rightpoint-leftpoint)+leftpoint;
}
}
}
GenAlg::GenAlg()
{
}
void GenAlg::Reset()
{
totalfitness=0;
averagefitness=0;
}
void GenAlg::report(int numgen)
{
cout<<"第"<<numgen<<"代"<<endl;
cout<<"最佳适应度为:"<<bestone.fitness<<endl;//bestone由CalculateBestWorstAveTol()计算出
cout<<"最佳适应度基因为:"<<bestone.vecGenome[0]<<endl;
cout<<"平均适应度为:"<<averagefitness<<endl;
}
void GenAlg::Calculatebestworstavetol()
{
for(int i=0;i<popsize;i++)
{
totalfitness+=vecPop[i].fitness;
if(vecPop[i].fitness>=bestfitness)
{
bestfitness=vecPop[i].fitness;
bestone.vecGenome=vecPop[i].vecGenome;
bestone.fitness=bestfitness;
}
if(vecPop[i].fitness<=worstfitness)
worstfitness=vecPop[i].fitness;
}
averagefitness=totalfitness/popsize;
}
void GenAlg::Mutate(vector<double> &chrome)
{
for(int i=0;i<Genomelength;i++) //单个人的基因突变
{
if(random()<mutationrate)
{
chrome[i]+=(random()-0.5)*maxperturtation;
}
if(chrome[i]>rightpoint)chrome[i]=leftpoint;
if(chrome[i]<leftpoint)chrome[i]=rightpoint;
}
}
Genome GenAlg::GetGenomeRoulette()
{
Genome vecnewGenome;
double slice=random()*totalfitness;
double fitnesssofar=0;
for(int i=0;i<popsize;i++)
{
if(fitnesssofar>=slice)
{
vecnewGenome=vecPop[i];//不是vecnewGenome=vecPop[i].vecGenome;
break;
}
else fitnesssofar=fitnesssofar+vecPop[i].fitness;
}
return vecnewGenome;
}
GenEngine::GenEngine(int popSize,double MutRate,double CrossRate,int GenLenght,int Generation,
double LeftPoint,double RightPoint)
{
//genAlg();不要用genAlg(),curve(),m_population(),不知道模板那边为什么可以用,这三个是成员而不是函数,不能用函数调用方式
g_population.clear(); //新的种群基因库,vector(Genome)类
g_popSize=popSize;
g_MutRate=MutRate;
g_CrossRate=CrossRate;
g_GenLenght=GenLenght;//Genome中基因的个数
g_Generation=Generation;//迭代的总次数
//应该不需要了numgeneration=0;迭代的计数器,直接在OnStartGenAlg中用临时变量实现
g_LeftPoint=LeftPoint;
g_RightPoint=RightPoint;
}
void GenAlg::Epoch(vector<Genome> &vecNewPop) //vecNewPop引用在g_population上
{
vecPop=vecNewPop;// 不是g_population=vecNewPop;/
Reset();//为了避免totalfitness被叠加,但是感觉也可以在OnStartGenAlg中用genAlg.Reset实现
//源代码CalculateBestWorstAvTol()被加在这处,感觉也可以在OnStartGenAlg中用genAlg.CalculateBestWorstAvTol()实现
vecNewPop.clear();
for(int i=0;i<popsize;i++)
{
// Genome mum=GetGenomeRoulette();因为不存在交叉,所以不设父母双方,并且要是同时生成两个子代要是
Genome dad=GetGenomeRoulette();
vector<double> baby1=dad.vecGenome;
//Genome baby2=dad;
Mutate(baby1);
vecNewPop.push_back(Genome(baby1,0));//不能这样写vecNewPop.push_back(baby1,0);
}
}
void GenEngine::OnStartGenAlg()
{
srand( (unsigned)time( NULL ) );
genAlg.init(g_popSize,g_MutRate,g_CrossRate,g_GenLenght,g_LeftPoint,g_RightPoint);//用GenEngine中的元素是因为genAlg是GenEngine
//的元素,这样初始化GenEngine后,数值就可以流向genAlg
//这里不用g_population.clear是因为在GenEngine.init时就把其清空了
g_population.clear();//加clear函数是为了
g_population=genAlg.vecPop;
vector<double> input;
double output;
for(int Generation=0;Generation<g_Generation;Generation++)
{
for(int i=0;i<g_popSize;i++)
{
input=g_population[i].vecGenome;
output=(double)curve.function(input);//这里不能用output=(double)Curve.function(input)
g_population[i].fitness=output;
}
genAlg.Epoch(g_population);
genAlg.Calculatebestworstavetol();
genAlg.report(Generation+1);
}
}
主函数
#include<iostream>
#include"class.h"
using namespace std;
void main()
{
GenEngine genEngine(50,0.8,0.8,1,100,-1,2);
genEngine.OnStartGenAlg();
}
不知道为什么运行出来会有
Damage:after Normal block(#58) at 0x00832B08的提示
0x00832B08是代表行数吗