遗传算法在游戏中的应用——y=x^2

来源:互联网 发布:简繁体转换软件 编辑:程序博客网 时间:2024/05/21 09:14

通过上一篇文章的讲解,应该大概了解遗传算法的大概。这一篇我们来讲解简单遗传算法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;elsemid=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){}


0 0