遗传算法在游戏中的应用——y=x^2
2016-03-29 21:43
357 查看
通过上一篇文章的讲解,应该大概了解遗传算法的大概。这一篇我们来讲解简单遗传算法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;
//
};
简单遗传算法类:
编译环境: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) { }
相关文章推荐
- C++实现遗传算法
- javascript制作游戏开发碰撞检测的封装代码
- Android游戏开发实践之人物移动地图的平滑滚动处理
- 深入理解Java遗传算法
- 8.Utm示例-Netty集成
- 3.Utm详细实现-用户生命流程
- 2.Utm-模块设计
- 4.Utm详细实现-用户资源管理
- 7.Utm示例-SmartFoxServer集成
- 5.Utm线程模型
- 6.Utm示例-公共部分
- UTM 用户线程模型
- 游戏服务器端开发要点
- tvOS游戏开发系列(SpriteKit)之准备工作(一)
- tvOS游戏开发系列(SpriteKit)之新建tvOS游戏项目(二)
- 开源游戏 “打飞机”
- 开源游戏 “Elvish Bird”
- 开源游戏“2048”IOS移植版
- 游戏开发如何成功
- 【v2.x OGE教程 15】布局相关