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

通过上一篇文章的讲解,应该大概了解遗传算法的大概。这一篇我们来讲解简单遗传算法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)
{
}
    原文作者:遗传算法
    原文地址: https://blog.csdn.net/jin_syuct/article/details/51009535
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞