进化计算的简单例子

本文介绍了一个使用C++实现的遗传算法示例,通过具体的代码展示了种群初始化、选择、交叉、变异等遗传操作的过程,并利用轮盘赌选择法进行种群更新。
#include<iostream>
#include<string>
#include<time.h>
#include<sstream>
using namespace std;


//种群总数
const int popSize = 100;
//染色体长度
const int chromosomeSize = 9;
//变异概率
const double Pm = 0.001;
//最多代数
const int MaxGen = 100;
//变异概率
const double Pc = 0.1;





//遗传个体类
class individual
{
public:
	//个体目标值
	double ObjectValue;
	//个体适应值
	double FitValue;
	//染色体编码
	string Chromosome;
	//构造函数
	individual()
	{
		ObjectValue = 0;
		FitValue = 0;
		Chromosome = "000000000";
	}
};

//进化处理类
class Evaluation
{
private:

	//种群
	individual Population[popSize];
	//进行选择
	void SelectPop();
	//进行变异
	void VaryPop();
	//进行杂交
	void CrossPop();
	//优化
	void OptimizePop();
	//初始化种群,随机构造一个群体
	void Initialization();
	//找出最优和最差及平均值
	void Statistics();
	//评价种群
	void EvaluatePop();
	//最好个体
	individual Best;
	//最坏个体
	individual Worst;
	//最坏个体下标
	int WorstIndex;
	//历史最佳
	individual HistoryBest;
	//平均值
	double avg;

public:
	//构造函数,调用初始化函数
	Evaluation();
	//产生下一代
	void NextPopulation();
	//打印
	void output();
	//代数
	int generation;
};

//构造函数,调用初始化函数
Evaluation::Evaluation()
{
	Initialization();
	generation = 0;

}

//初始化构造初始种群
void Evaluation::Initialization()
{
	//对染色体进行初始化设置,逐颗粒随机赋值
	char temp;
	int Index = 0, bitIndex = 0;
	for (; Index<popSize; Index++)
	{
		for (bitIndex = 0; bitIndex<chromosomeSize; bitIndex++)
		{
			int r = rand() % 2;
			if (r == 0)
				temp = '0';
			else
				temp = '1';
			Population[Index].Chromosome[bitIndex] = temp;
		}
	}
	//初始化时设置历史最佳为第一个
	HistoryBest = Population[0];
	//调用目标值和适应值的初始化函数,评价种群
	EvaluatePop();
	Statistics();
}

//评价函数,就是用函数f(x1,x2)=x1^2+x2^2,因为是数值函数,所以适应值和目标值是一致的
void Evaluation::EvaluatePop()
{
	string num1, num2, num3;
	int value1, value2, value3;
	int Index = 0;
	for (; Index<popSize; Index++)
	{
		num1 = Population[Index].Chromosome.substr(0, 3);
		num2 = Population[Index].Chromosome.substr(3, 3);
		num3 = Population[Index].Chromosome.substr(6, 3);
		//二进制转化为十进制
		stringstream ss;
		ss << num1;
		ss >> value1;
		//清空缓冲区
		ss.clear();
		ss.str("");
		ss << num2;
		ss >> value2;
		//清空缓冲区
		ss.clear();
		ss.str("");
		ss << num3;
		ss >> value3;

		int a, b, c;
		a = value1 / 100;
		b = (value1 - a * 100) / 10;
		c = value1 - a * 100 - b * 10;
		value1 = a * 4 + b * 2 + c;
		a = value2 / 100;
		b = (value2 - a * 100) / 10;
		c = value2 - a * 100 - b * 10;
		value2 = a * 4 + b * 2 + c;
		a = value3 / 100;
		b = (value3 - a * 100) / 10;
		c = value3 - a * 100 - b * 10;
		value3 = a * 4 + b * 2 + c;
		//计算适应值和目标值
		Population[Index].FitValue = value1*value1 + value2*value2 + value3*value3;
		Population[Index].ObjectValue = value1*value1 + value2*value2 + value3*value3;
	}
}

//生成下一代
void Evaluation::NextPopulation()
{
	SelectPop();
	VaryPop();
	CrossPop();
	EvaluatePop();
	Statistics();
	OptimizePop();
	EvaluatePop();
	Statistics();
	generation++;
}

//选择算子,轮盘赌
void Evaluation::SelectPop()
{
	double FitSum = 0, selection[popSize];
	individual newPopulation[popSize];
	int index = 0, popindex = 0;
	//求适应值的总和
	for (; index<popSize; index++)
	{
		FitSum += Population[index].FitValue;
	}

	//确定轮盘分布
	for (index = 0; index<popSize; index++)
	{
		selection[index] = Population[index].FitValue / FitSum;
	}
	for (index = 1; index<popSize; index++)
	{
		selection[index] = selection[index] + selection[index - 1];
	}
	//用轮盘进行随机选取,形成新的种群
	for (popindex = 0; popindex<popSize; popindex++)
	{
		double p = (rand() % 100);
		p /= 100;
		index = 0;
		while (p>selection[index])
			index++;
		newPopulation[popindex] = Population[index];
	}
	//将刚产生的群体替换为系统的群体
	for (index = 0; index<popSize; index++)
	{
		Population[index] = newPopulation[index];
	}

}

//杂交算子,随机选取交叉点
void Evaluation::CrossPop()
{
	int Localtion;
	int index = 0;
	string str1, str2, str3, str4;
	//打乱顺序
	for (; index<popSize; index++)
	{
		individual temp;
		int r = rand() % popSize;
		temp = Population[index];
		Population[index] = Population[r];
		Population[r] = temp;
	}
	//随机选取交叉点,将染色体分裂,然后交叉,得到新的染色体
	for (index = 0; index<popSize; index += 2)
	{
		double temp = rand() % 1000 / 1000.0;
		if (temp<Pc)
		{
			Localtion = rand() % chromosomeSize;
			str1 = Population[index].Chromosome.substr(0, Localtion);
			str2 = Population[index].Chromosome.substr(Localtion);
			str3 = Population[index + 1].Chromosome.substr(0, Localtion);
			str4 = Population[index + 1].Chromosome.substr(Localtion);
			Population[index].Chromosome = str1 + str4;
			Population[index + 1].Chromosome = str3 + str2;
		}
	}
}

//变异算子,对所有染色体每一位的随机位置以变异概率进行变异
void Evaluation::VaryPop()
{
	int index = 0, bitindex = 0;
	string str1 = "0";
	string str2 = "1";

	for (; index<popSize; index++)
	{
		for (bitindex = 0; bitindex<chromosomeSize; bitindex++)
		{
			double r = rand() % 1000;
			r /= 1000;
			if (r<Pm)
			{
				if (Population[index].Chromosome[bitindex] == str1[0])
					Population[index].Chromosome[bitindex] = str2[0];
				else
					Population[index].Chromosome[bitindex] = str1[0];
			}
		}
	}
}

//优化
void Evaluation::OptimizePop()
{
	Population[WorstIndex] = HistoryBest;
}

//统计
void Evaluation::Statistics()
{
	Best = Population[0];
	Worst = Population[0];
	int index = 0;
	double sum = 0;
	for (; index<popSize; index++)
	{
		if (Best.FitValue<Population[index].FitValue)
			Best = Population[index];
		if (Worst.FitValue>Population[index].FitValue)
		{
			Worst = Population[index];
			WorstIndex = index;
		}
		sum += Population[index].FitValue;
	}
	if (HistoryBest.FitValue<Best.FitValue)
		HistoryBest = Best;
	avg = sum / popSize;

}


//输出文本
void Evaluation::output()
{
	cout << "Generation:" << generation << "   Average:" << avg << "   Best:" << Best.FitValue << "  Chromosome:" << Best.Chromosome << endl;
}


int main()
{
	Evaluation eva;
	eva.output();
	while (eva.generation<MaxGen)
	{
		eva.NextPopulation();
		eva.output();
	}
	int a;
	cin >> a;

}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值