通过上一篇文章的讲解,应该大概了解遗传算法的大概。这一篇我们来讲解简单遗传算法SGA中的一个例子:Y=x^2。通过这个例子,我们就可以清楚的知道,遗传算法是怎么操作的。
编译环境:VS2012,c++11
主函数:
#include "stdafx.h"
#include"math.h"
#include"SGA.h"
int _tmain(int argc, _TCHAR* argv[])
{
SGA *s=SGA::createSGA(0.01,0.2,5,10,5);
s->initgenertion();
s->generatenextpopulation();
return 0;
}
这里我们主要考虑到,代码的复用性。所以讲算子函数定义成了虚函数,也就是接口,不同的问题可能选择,交叉,变异操作是一样的,计算适应度是不一样的,这时候只需要继承这个类,然后重载计算适应度函数,就可以了。
#pragma once
#include<math.h>
class GA
{
public:
GA(void);
~GA(void);
//选择操作
virtual void selectoperator()=0;
//交换操作
virtual void crossoveroperator()=0;
//计算种群适应度
virtual void calculateobjectfitness()=0;
//变异操作
virtual void mutationoperator()=0;
//
};
简单遗传算法类:
#pragma once
#include<vector>
#include"individual.h"
#include"GA.h"
using std::vector;
using std::iterator;
using namespace std;
class SGA:public GA
{
public:
SGA(void);
~SGA(void);
//
bool init(double pc,double pm,int maxgenertion,int popsize,int chromlength);
//初始化种群
void initgenertion();
//评估种群
void evaludatepop();
//选择函数
virtual void selectoperator();
//交换操作
virtual void crossoveroperator();
//变异操作
virtual void mutationoperator();
//计算种群适应度
virtual void calculateobjectfitness();
//
virtual void printfindividual(int generation);
//产生下一代种群
void generatenextpopulation();
//染色体解码
double decodechromosome();
//构造一个简单遗传学算法
static SGA* createSGA(double pc,double pm,int maxgenertion,int popsize,int chromlength);
private:
double m_pc;// 变异率
double m_pm;//交叉率
int m_maxgenertion;//最大是代数
int m_popsize;//种群大小
int m_chromlength;//染色体长度
vector<individual> m_individual;
};
简单遗传算法.cpp文件
#include "stdafx.h"
#include "SGA.h"
#include<time.h>
#include<iostream>
#include<iterator>
double const denominator=0.0001f;
SGA::SGA(void)
{
srand((unsigned)time(NULL));
}
/*
创建一个简单遗传算法,参数分别是变异率,交叉率,最大世代数,种群大小,基因长度
*/
SGA* SGA::createSGA(double pc,double pm,int maxgenertion,int popsize,int chromlength)
{
SGA* sga=new SGA();
if(sga&&sga->init(pc,pm,maxgenertion,popsize,chromlength))
{
return sga;
}
else{
delete sga;
return NULL;
}
}
bool SGA::init(double pc,double pm,int maxgenertion,int popsize,int chromlength)
{
bool flg=true;
m_pc=pc;
m_pm=pm;
m_maxgenertion=maxgenertion;//最大是代数
m_popsize=popsize;//种群大小
m_chromlength=chromlength;//染色体长度
if(popsize==0||maxgenertion==0||chromlength==0)
{
flg=false;
}
return flg;
}
void SGA::initgenertion()
{
int i,j,mid;
if(m_chromlength>6)
mid=m_chromlength/2;
else
mid=m_chromlength;
srand((unsigned)time(NULL));
for(i=0;i<m_popsize;i++)
{
individual temp;
for(j=0;j<m_chromlength;j++)
{
int c=rand()%10>mid?0:1;
temp.chrom.push_back(c);
}
m_individual.push_back(temp);
}
evaludatepop();
printfindividual(1);
}
double SGA::decodechromosome()
{
for(auto it=m_individual.begin();it!=m_individual.end();it++)
{
int index=0;
int sum=0;
for(auto i=it->chrom.begin();i!=it->chrom.end();i++)
{
auto temp=*i;
sum+=temp*pow(2.0f,index);
index++;
}
it->value=sum;
}
//printfindividual();
return 0;
}
void SGA::evaludatepop()
{
//染色体解码
decodechromosome();
//计算个体的适应度
calculateobjectfitness();
}
void SGA::crossoveroperator()
{
//printfindividual();
//cout<<"变异之后:"<<endl;
vector<individual> temp;
vector<int> list;
//打乱个体顺序
for(int i=0;i<m_popsize;i++)
{
list.push_back(i);
}
for(int i=0;i<m_popsize;i++)
{
int index=rand()%(m_popsize-i);
if(index==i)
index++;
/*auto t=list[index];
list[i]=t;
list[index]=t;*/
swap(list[index],list[i]);
}
for(int i=0;i<m_popsize;i++)
{
auto p=rand()%100/100.0f;
if(p<m_pm)
{
int index=list[i];
if(index==i)
index++;
/*auto temp=m_individual[i].chrom;
m_individual[i].chrom=m_individual[index].chrom;
m_individual[index].chrom=temp;*/
swap(m_individual[i],m_individual[index]);
/* cout<<"变异位置:"<<endl;
cout<<i<<","<<index<<endl;*/
}
}
//printfindividual();
}
void SGA::selectoperator()
{
int sum=0;
vector<double> confess;
vector<individual> newpop;
srand((unsigned)time(NULL));
// 求和
for(auto it=m_individual.begin();it!=m_individual.end();it++)
{
auto fitness=it->fitness;
sum+=fitness;
}
for(auto it=m_individual.begin();it!=m_individual.end();it++)
{
auto p=it->fitness/sum;
it->pre=p;
confess.push_back(p);
}
for(auto it=1;it<confess.size();it++)
{
confess[it]=confess[it]+confess[it-1];
}
for(auto it=0;it<m_popsize;it++)
{
auto p=rand()%1000*0.001;
int index=0;
for(auto i=confess.begin();i!=confess.end();i++)
{
if(p>(*i)){
index++;
}else{
break;
}
}
auto indivi=m_individual[index];
newpop.push_back(indivi);
}
//cout<<"这是选择后的个体"<<endl;
if(!newpop.empty())
m_individual=newpop;
printfindividual(1);
}
void SGA::mutationoperator()
{
srand((unsigned)time(NULL));
int num=0;
for(auto it=m_individual.begin();it!=m_individual.end();it++)
{
auto pc=rand()%1000*denominator;
if(pc<m_pc)
{
auto index=rand()%m_chromlength;
auto value=it->chrom[index];
value=value!=1?1:0;
//cout<<"交换后的值"<<value<<endl;
it->chrom[index]=value;
//cout<<"交换的位置:"<<index<<endl;
}
//cout<<"交换的染色体是哪一个:"<<num<<endl;
num++;
}
//evaludatepop();
}
void SGA::printfindividual(int generation)
{
cout<<"这是第"<<generation<<"代"<<endl;
int sum=0,average;
for(auto it=m_individual.begin();it!=m_individual.end();it++)
{
printf("染色体编码值:");
for(auto i=it->chrom.begin();i!=it->chrom.end();i++)
{
cout<<*i;
}
auto value=it->value;
sum+=value;
cout<<"个体函数值:"<<value;
auto fitness=it->fitness;
cout<<"个体适应度:"<<fitness;
auto pre=it->pre;
cout<<"概率:"<<pre;
auto cpre=it->accumulated_fitness;
cout<<"累计概率"<<cpre<<endl;
}
average=sum/m_popsize;
cout<<"当前种群的平均值:"<<average<<endl;
}
//计算个体是适应度
void SGA::calculateobjectfitness()
{
for(auto it=m_individual.begin();it!=m_individual.end();it++)
{
auto value=it->value;
auto fitness=value*value;
it->fitness=fitness;
}
}
void SGA::generatenextpopulation()
{
int generation=0;
while (generation<m_maxgenertion)
{
selectoperator();
crossoveroperator();
mutationoperator();
evaludatepop();
printfindividual(generation);
generation++;
}
}
SGA::~SGA(void)
{
}