c++ 遗传算法
这周完成了一个遗传算法的大作业,记录学习过程。
这里是一个遗传算法详细介绍的链接:
我的理解 :遗传算法就是给你一个函数F(x,y),让你在x,y的定义域内找出函数F(x,y)的全局最优解
它通过不断改变x,y的值来得出新的F(x,y),然后保留F(x,y)中比较满意的一部分,剩余部分直接淘汰。
每次改变,保留,淘汰都是一次迭代的过程,直到得到F(x,y)的全局最优(理论上无限次迭代的结果,实际可能陷入局部最优,如基因码多个连续的0或多个连续的1)
题目:
我第一次实现的版本:它的时间效率比较低,因为每一次迭代的每一个个体都要进行一次基因码解码为表现型。而解码一次需要23ms,太费时间。
第二个版本我就把基因型和表现型做了一个映射,把解码过的基因和x1,x2,表现型记录下来,每次解码时首先去映射表查找有没有解码过,解码过就直接赋值,省去解码的过程,效率飞升。
我用的是visual studio2019
第一代版本:
#include<iostream>
#include<cmath>
#include<vector>
#include<time.h>
#include <stdlib.h>
#include<iomanip>
using namespace std;
//声明全局变量
//种群数量N,精英数量E,迭代次数Times,两点交叉概率Pc,单点变异概率Pm;
int N = 100, E = 5, Times = 500;
double Pc = 0.6, Pm = 0.06, PI = 3.1415926;
//初始化,随机创建N个个体的初始基因型:int Individual[N][33]
void Initialize(vector<vector<int>> &Individual)
{
//随机创建N个个体的初始基因型
for (int i = 0; i < N; i++) //遍历每个个体v
{
for (int j = 0; j < 33; j++) //每个个体随机33位01基因序列
{
Individual[i][j] = (rand() % 2);
}
}
}
//改进测试:不使用库函数是否加快函数运算速度;结论:无明显变化
int Pow(int k)
{
int r=1;
for (int i = 0; i < k; i++)
r = r * 2;
return r;
}
//解码,返回第i个个体的表现型
double Decode(vector<vector<int>> Indivisual, int i)
{
//声明解码值x1,x2
double x1 = 0, x2 = 0;
//解码x1
int TempSum = 0;
for (int j = 17, k = 0; j >= 0; j--, k++)
{
TempSum += Pow( k) * Indivisual[i][j];
}
x1 = TempSum * 15.1 / 262143 - 3;
//解码x2
TempSum = 0;
for (int j = 32, k = 0; j >= 18; j--, k++)
{
TempSum += Pow( k) * Indivisual[i][j];
}
x2 = TempSum * 1.7 / 32767 + 4.1;
//返回fit值
return 21.5 + x1 * sin(4 * PI * x1) + x2 * sin(20 * PI * x2);
}
//计算个体的表现型
void ComFit(vector<vector<int>>& Individual, double Fit[])
{
for (int i = 0; i < N; i++)
{
//个体i的基因型解码为表现型
Fit[i] = Decode(Individual, i);
}
}
//精英保留
void Save(vector<vector<int>>& Individual, int EliteNum[], vector<vector<int>>& EliteGene,double Fit[],double EliteValue[])
{
//精英保留E个最优个体直接进入下一代种群
for (int i = 0; i < E; i++) //循环找出E个精英交叉池编号 i表示第i个精英
{
double MaxFit = 0;
for (int j = 0; j < N; j++) //遍历所有个体适应值,找出第i个精英 j表示当前个体
{
// <=更改为<
if (MaxFit < Fit[j]) //判断当前最大适应值是否小于等于当前个体适应值
{
int repeat = 0;
for (int k = 0; k < E; k++) //遍历所有精英,判断当前精英是否重复
{
if (j == EliteNum[k]) //
{
repeat = 1;
break;
}
}
if (repeat == 0) //当前精英未重复
{
MaxFit = Fit[j];
EliteValue[i] = MaxFit;
EliteNum[i] = j;
for (int ii = 0; ii < 33; ii++)
{
EliteGene[i][ii] = Individual[j][ii];
}
}
else
continue;
}
}
}
}
//把父代Individual[][]中第i个体放入交叉池pool中,
void CopyIn(vector<vector<int>>& Pool, vector<vector<int>>& Individual, int i, int j)
{
for (int k = 0; k < 33; k++)
Pool[i][k] = Individual[j][k];
return;
}
//建立交叉池
void CreatePool(vector<vector<int>>& Individual, vector<vector<int>>& Pool, double Fit[])
{
//首先,计算个体的适应度占总适应度的比值pi,然后,计算个体的累计适应度qi。
double* pi = new double[N];
double* qi = new double[N];
//求总适应度sum_fit
double sum_fit = 0;
for (int i = 0; i < N; i++)
sum_fit += Fit[i];
//遍历所有个体适应度,求每个个体/比值pi,每个个体累计适应度qi
for (int i = 0; i < N; i++)
{
pi[i] = Fit[i] / sum_fit;
if (i == 0)
qi[i] = pi[i];
else
qi[i] = qi[i - 1] + pi[i];
}
for (int i = 0; i < N; i++)
{
//轮盘赌选择概率p
double p = (rand() % 10000 / 10001.0);
for (int j = 0; j < N; j++)
if (qi[j] > p)
{
// 把N个体放入交叉池
CopyIn(Pool, Individual, i, j);
break;
}
}
delete[]pi;
delete[]qi;
}
//在交叉池内进行两点交叉
void TwoPointCross(vector<vector<int>>& Pool, int i)
{
int left = rand() % 33, right = rand() % 33;
if (left > right)
{
int t = left;
left = right;
right = t;
}
for (int j = left; j <= right; j++)
{
int temp = Pool[i][j];
Pool[i][j] = Pool[i + 1][j];
Pool[i + 1][j] = temp;
}
}
//单点变异
void SinglePointVariation(vector<vector<int>>& Pool, int i, double Pm)
{
for (int j = 0; j < 33; j++)
{
if (Pm > (rand() % 10000 / 10001.0))
{
Pool[i][j] = (Pool[i][j] + 1) % 2;
}
}
}
//两点交叉,单点变异
void IndiCrossVariation(vector<vector<int>>& Pool)
{
for (int i = 0; i < N / 2; i++)
{
//随机值小于交叉概率则进行两点交叉
if (Pc > (rand() % 10000 / 10001.0))
{
//在交叉池内进行两点交叉
TwoPointCross(Pool, i);
//对交叉的个体的两个后代进行单点变异
SinglePointVariation(Pool, i, Pm);
}
}
}
//计算交叉池个体的表现型
void CalculationFit(vector<vector<int>>& DoubleIndi, double DoubleFit[])
{
//计算表现型
for (int i = 0; i < N*2; i++)
{
//个体i的基因型解码为表现型
DoubleFit[i] = Decode(DoubleIndi, i);
}
}
//计算累计适应度
void CalculationDoubleQi(double DoubleFit[], double DoublePi [] , double DoubleQi[])
{
//求总适应度sum_fit
double SumFitAll = 0;
int i;
for (i = 0; i < N*2; i++)
SumFitAll += DoubleFit[i];
//遍历所有个体适应度,求每个个体/比值,每个个体累计适应度
for (i = 0; i < N*2; i++)
{
DoublePi[i] = DoubleFit[i] / SumFitAll;
if (i == 0)
DoubleQi[i] = DoublePi[i];
else
DoubleQi[i] = DoubleQi[i - 1] + DoublePi[i];
}
}
void UpdataPopulation(vector<vector<int>>& Individual, vector<vector<int>>& Pool, vector<vector<int>>& EliteGene)
{
//把父代和子代放入种群池DoubleIndi
vector<vector<int>> DoubleIndi(2 * N, vector<int>(33));
int i, j;
for (i = 0; i < N; i++)
{
for (j = 0; j < 33; j++)
{
DoubleIndi[i][j] = Individual[i][j];
}
}
for (i = N; i < 2 * N; i++)
for (j = 0; j < 33; j++)
{
DoubleIndi[i][j] = Pool[i - N][j];
}
//创建适应度数组
double* DoubleFit = new double[2 * N];
//创建个体的适应度占总适应度的比值
double* DoublePi = new double[2 * N];
//创建累计适应度数组
double* DoubleQi = new double[2 * N];
//计算所有个体适应度,返回 DoubleFit
CalculationFit(DoubleIndi, DoubleFit);
//计算累计适应度,返回DoubleQi
CalculationDoubleQi(DoubleFit, DoublePi, DoubleQi);
//从种群 DoubleIndi中轮盘赌选择 N-E 个个体进入下一代 Individual[N][33]
for (i = 0; i < N - E; i++)
{
double p2 = rand() % 10000 / 10001.0;
//cout << p2 << endl;
for (j = 0; j < N * 2; j++)
{
if (DoubleQi[j] > p2)
{
CopyIn(Individual, DoubleIndi, i, j);
break;
}
}
}
//精英个体EliteGene[E][33]直接加入下一代 Individual[N][33]
for (j = 0; j < E; j++, i++)
{
for (int k = 0; k < 33; k++)
Individual[i][k] = EliteGene[j][k];
}
delete[]DoubleFit;
delete[]DoublePi;
delete[]DoubleQi;
}
void Decodex1(vector<vector<int>>& EliteGene, double x1[])
{
//解码x1
for (int i = 0; i < E; i++)
{
int TempSum = 0;
for (int j = 17, k = 0; j >= 0; j--, k++)
{
TempSum += (int)pow(2, k) * EliteGene[i][j];
}
x1[i] = TempSum * 15.1 / 262143 - 3;
}
}
void Decodex2(vector<vector<int>>& EliteGene, double x2[])
{
//解码x2
for (int i = 0; i < E; i++)
{
int TempSum = 0;
for (int j = 32, k = 0; j >= 18; j--, k++)
{
TempSum += (int)pow(2, k) * EliteGene[i][j];
}
x2[i] = TempSum * 1.7 / 32767 + 4.1;
}
}
//输出精英的适应值和基因码
void OutputElite(double EliteValue[], vector<vector<int>>& EliteGene,int Current_t,double x1[],double x2[])
{
Decodex1(EliteGene, x1);
Decodex2(EliteGene, x2);
//输出精英的适应值
for (int i = 0; i < E; i++)
{
cout << "种群第" << Current_t << "代第" << i << "个精英个体的精英适应值:" <<fixed<<setprecision(15)<< EliteValue[i];
cout << " 它的f(x1,x2)=(" << x1[i] << "," << x2[i] << ") " << " 它的基因码:";
for (int j = 0; j < 33; j++)
{
cout << EliteGene[i][j];
}
cout << endl;
}
cout << endl;
}
int main()
{
//创建随机数种子
srand((unsigned)time(NULL));
//创建N个个体 Individual[N][33]
vector<vector<int>> Individual(N, vector<int>(33));
//对应个体的表现型 Fit[N]
double* Fit = new double[N]();
//声明精英个体编号,寻找适应值最大的E个个体的种群编号EliteNum[E]
int* EliteNum = new int[E]();
//声明精英保存数组
vector<vector<int>> EliteGene(E,vector<int>(33));
//定义E个精英的适应值EliteValue[],并初始化
double* EliteValue = new double[E]();
//初始化,随机创建N个个体的初始基因型:int Individual[N][33]
Initialize(Individual);
//迭代Times次
for (int Current_t = 0; Current_t < Times; Current_t++)
{
//计算个体的表现型
ComFit(Individual, Fit);
//保留E个适应度最高的精英:double Elite[E] ,以及它的基因型 int EliteGene[E][33]
Save(Individual, EliteNum, EliteGene, Fit, EliteValue);
//轮盘赌选择创建交叉池 int Pool[N][33]
vector<vector<int>> Pool(N, vector<int>(33));
CreatePool(Individual, Pool, Fit);
//种群个体间基因在交叉池两点交叉以及单点变异 产生在交叉池中的子代 int Pool[N][33]
IndiCrossVariation(Pool);
//把父代和子代合并,进行轮盘赌选择N-E个个体,更新种群个体 Individual[N-E][33]
UpdataPopulation(Individual, Pool,EliteGene);
//输出当前代的精英表现形(适应值)以及基因型
//
double* x1 = new double[E];
double* x2 = new double[E];
OutputElite(EliteValue, EliteGene,Current_t,x1,x2);
delete[] x1;
delete[] x2;
}
cout << "OK" << endl;
delete[]Fit;
delete[]EliteNum;
delete[]EliteValue;
return 0;
}
第二代优化版:
#include<iostream>
#include<cmath>
#include<vector>
#include<time.h>
#include <stdlib.h>
#include<iomanip>
using namespace std;
//声明全局变量
//种群数量N,精英数量E,迭代次数Times,两点交叉概率Pc,单点变异概率Pm,纪元T;映射表指针GMFnum
int N = 100, E = 10, Times = 2000, T = 100,GMFnum=0;
double Pc = 0.6, Pm = 0.06, PI = 3.1415926;
//种群
class Population
{
public:
int gene[33],fitChange;
double x1, x2, fit;
//随机初始化个体基因
void Initialize()
{
for (int i = 0; i < 33; i++)
gene[i] = (rand() % 2);
fitChange = 1;
fit = 100; x1 = 100; x2 = 100;
}
};
//精英
class Elite
{
public:
int num;
int gene[33];
double x1, x2, fit;
//初始化精英在种群中的序号全为0
Elite()
{
num = 0;
}
};
//映射表
class GeneMappingFit
{
public:
int gene[33];
double x1, x2, fit;
//初始化基因全为0
GeneMappingFit()
{
x1 = 100; x2 = 100; fit = 0;
for (int i = 0; i < 33; i++)
gene[i] = 0;
}
};
//判断个体i是否在映射表中,是则返回映射表序号,否则返回-1;
int GeneInGMF(Population Individual[], int i, GeneMappingFit gmf[])
{
int j, same = 1;
//遍历映射表gmf
for (j=0; j < N; j++)
{
for (int k = 0; k < 33; k++)
{
if (Individual[i].gene[k] == gmf[j].gene[k])
;
else
{
same = 0;
break;
}
}
if (same == 1)
{
return j;
}
}
//判断个体i在映射表中,返回j
return -1;
}
//个体i不在映射表中,计算个体i表现型; 更新Indivisual[i].fitChange = 0; 更新映射表;
void DecodeAndUpdata(Population Indivisual[],int i, GeneMappingFit gmf[])
{
//解码x1
int TempSum = 0;
for (int j = 17, k = 0; j >= 0; j--, k++)
{
TempSum += (int)pow(2, k) * Indivisual[i].gene[j];
}
Indivisual[i].x1 = TempSum * 15.1 / 262143 - 3;
//解码x2
TempSum = 0;
for (int j = 32, k = 0; j >= 18; j--, k++)
{
TempSum += (int)pow(2, k) * Indivisual[i].gene[j];
}
Indivisual[i].x2 = TempSum * 1.7 / 32767 + 4.1;
Indivisual[i].fit=21.5 + Indivisual[i].x1 * sin(4 * PI * Indivisual[i].x1) + Indivisual[i].x2 * sin(20 * PI * Indivisual[i].x2);
Indivisual[i].fitChange = 0;
//更新映射表
if (GMFnum < N)
{
gmf[GMFnum].fit = Indivisual[i].fit;
gmf[GMFnum].x1 = Indivisual[i].x1;
gmf[GMFnum].x2 = Indivisual[i].x2;
for (int k = 0; k < 33; k++)
gmf[GMFnum].gene[k] = Indivisual[i].gene[k];
GMFnum++;
}
else
{
GMFnum -= N;
gmf[GMFnum].fit = Indivisual[i].fit;
gmf[GMFnum].x1 = Indivisual[i].x1;
gmf[GMFnum].x2 = Indivisual[i].x2;
for (int k = 0; k < 33; k++)
gmf[GMFnum].gene[k] = Indivisual[i].gene[k];
}
}
//个体i在映射表中,映射表直接赋值,fitChange=0
void CopyIn(Population Individual[], int i, GeneMappingFit gmf[], int g)
{
Individual[i].fit = gmf[g].fit;
Individual[i].x1 = gmf[g].x1;
Individual[i].x2 = gmf[g].x2;
for (int k = 0; k < N; k++)
Individual[i].gene[k]= gmf[g].gene[k];
Individual[i].fitChange = 0;
}
//计算个体的表现型:判断个体fitChange是否为1(表示基因型与表现型不符)
void ComputeFit(Population Individual[],GeneMappingFit gmf[])
{
for (int i = 0; i < N; i++) //遍历所有个体
{
if (Individual[i].fitChange == 1) //当前个体基因型与表现型不符
{
//判断基因是否在映射表中,在g=映射表序号,反之g=-1
int g = GeneInGMF(Individual, i,gmf);
if (g == -1)
{
//个体i不在映射表中,计算个体表现型;更新Individual[i].fitChange = 0; 更新映射表;
DecodeAndUpdata(Individual, i,gmf);
}
else
{
//个体i在映射表中,映射表直接赋值,fitChange=0
CopyIn(Individual,i, gmf, g);
}
}
}
}
//精英保留
void Save(Population Individual[], Elite elite[])
{
//精英保留E个最优个体直接进入下一代种群
for (int i = 0; i < E; i++) //循环找出E个精英交叉池编号 i表示第i个精英
{
double MaxFit = 0;
for (int j = 0; j < N; j++) //遍历所有个体适应值,找出第i个精英 j表示当前个体
{
// <=更改为<
if (MaxFit < Individual[j].fit) //判断当前最大适应值是否小于等于当前个体适应值
{
int repeat = 0;
for (int k = 0; k < E; k++) //遍历所有精英,判断当前精英是否重复
{
if (j == elite[k].num) //
{
repeat = 1;
break;
}
}
if (repeat == 0) //当前精英未重复
{
MaxFit = Individual[j].fit;
elite[i].fit = MaxFit;
elite[i].num = j;
elite[i].x1= Individual[j].x1;
elite[i].x2 = Individual[j].x2;
for (int ii = 0; ii < 33; ii++)
{
elite[i].gene[ii] = Individual[j].gene[ii];
}
}
else
continue;
}
}
}
}
//建立交叉池
void CreatePool(Population Individual[], Population pool[])
{
//首先,计算个体的适应度占总适应度的比值pi,然后,计算个体的累计适应度qi。
double* pi = new double[N];
double* qi = new double[N];
//求总适应度sum_fit
double sum_fit = 0;
for (int i = 0; i < N; i++)
sum_fit += Individual[i].fit;
//遍历所有个体适应度,求每个个体/比值pi,每个个体累计适应度qi
for (int i = 0; i < N; i++)
{
pi[i] = Individual[i].fit / sum_fit;
if (i == 0)
qi[i] = pi[i];
else
qi[i] = qi[i - 1] + pi[i];
}
for (int i = 0; i < N; i++)
{
//轮盘赌选择概率p
double p = (rand() % 10000 / 10001.0);
for (int j = 0; j < N; j++)
if (qi[j] > p)
{
// 把N个体放入交叉池
pool[i].fit = Individual[j].fit;
pool[i].x1 = Individual[j].x1;
pool[i].x2 = Individual[j].x2;
pool[i].fitChange= Individual[j].fitChange;
for (int k = 0; k < 33; k++)
pool[i].gene[k] = Individual[j].gene[k];
break;
}
}
delete[]pi;
delete[]qi;
}
//在交叉池内进行两点交叉,交叉后不一样pool[i].fitChange = 1;
void TwoPointCross(Population pool[], int i)
{
int left = rand() % 33, right = rand() % 33;
if (left > right)
{
int t = left;
left = right;
right = t;
}
//判断两点交叉部分是否一样
int same = 1;
for (int j = left; j <= right; j++)
{
if (pool[i].gene[j] = pool[i + 1].gene[j])
;
else
{
same = 0;
break;
}
}
if (same == 1)
;
else
{
for (int k = left; k <= right; k++)
{
int temp = pool[i].gene[k];
pool[i].gene[k] = pool[i + 1].gene[k];
pool[i + 1].gene[k] = temp;
}
pool[i].fitChange = 1;
}
}
//单点变异,若变异成功pool[i].fitChange = 1;
void SinglePointVariation(Population pool[], int i, double Pm)
{
for (int j = 0; j < 33; j++)
{
if (Pm > (rand() % 10000 / 10001.0))
{
pool[i].gene[j] = (pool[i].gene[j] + 1) % 2;
pool[i].fitChange = 1;
}
}
}
//两点交叉,单点变异
void IndiCrossVariation(Population pool[])
{
for (int i = 0; i < N / 2; i++)
{
//随机值小于交叉概率则进行两点交叉
if (Pc > (rand() % 10000 / 10001.0))
{
//在交叉池内进行两点交叉
TwoPointCross(pool, i);
//对交叉的个体的两个后代进行单点变异 ,若变异成功pool[i].fitChange = 1;
SinglePointVariation(pool, i, Pm);
}
}
}
//计算个体的表现型:判断个体fitChange是否为1(表示基因型与表现型不符),是则
void ComputeDoubleFit(Population Individual[], GeneMappingFit gmf[])
{
for (int i = 0; i < 2 * N; i++) //遍历所有个体
{
if (Individual[i].fitChange == 1) //当前个体基因型与表现型不符
{
//判断基因是否在映射表中,在g=映射表序号,反之g=-1
int g = GeneInGMF(Individual, i, gmf);
if (g == -1)
{
//个体i不在映射表中,计算个体表现型;更新Individual[i].fitChange = 0; 更新映射表;
DecodeAndUpdata(Individual, i, gmf);
}
else
{
//个体i在映射表中,映射表直接赋值,fitChange=0
CopyIn(Individual, i, gmf, g);
}
}
}
}
//计算累计适应度
void CalculationDoubleQi(Population DoubleIndi[], double DoublePi[], double DoubleQi[])
{
//求总适应度sum_fit
double SumFitAll = 0;
int i;
for (i = 0; i < N * 2; i++)
SumFitAll += DoubleIndi[i].fit;
//遍历所有个体适应度,求每个个体/比值,每个个体累计适应度
for (i = 0; i < N * 2; i++)
{
DoublePi[i] = DoubleIndi[i].fit / SumFitAll;
if (i == 0)
DoubleQi[i] = DoublePi[i];
else
DoubleQi[i] = DoubleQi[i - 1] + DoublePi[i];
}
}
void UpdataPopulation(Population Individual[], Population pool[], Elite elite[], GeneMappingFit gmf[])
{
//把父代和子代放入种群池DoubleIndi
Population* DoubleIndi = new Population[N * 2];
int i, j;
for (i = 0; i < N; i++)
{
DoubleIndi[i].fit = Individual[i].fit;
DoubleIndi[i].x1 = Individual[i].x1;
DoubleIndi[i].x2 = Individual[i].x2;
DoubleIndi[i].fitChange = Individual[i].fitChange;
for (j = 0; j < 33; j++)
DoubleIndi[i].gene[j] = Individual[i].gene[j];
}
for (i = N; i < 2 * N; i++)
{
DoubleIndi[i].fit = pool[i - N].fit;
DoubleIndi[i].x1 = pool[i - N].x1;
DoubleIndi[i].x2 = pool[i - N].x2;
DoubleIndi[i].fitChange = pool[i - N].fitChange;
for (j = 0; j < 33; j++)
DoubleIndi[i].gene[j] = pool[i - N].gene[j];
}
//创建个体的适应度占总适应度的比值
double* DoublePi = new double[2 * N];
//创建累计适应度数组
double* DoubleQi = new double[2 * N];
//计算所有个体适应度,返回 DoubleFit
ComputeDoubleFit(DoubleIndi,gmf);
//计算累计适应度,返回DoubleQi
CalculationDoubleQi(DoubleIndi, DoublePi, DoubleQi);
//从种群 DoubleIndi中轮盘赌选择 N-E 个个体进入下一代 Individual[N][33]
for (i = 0; i < N - E; i++)
{
double p2 = rand() % 10000 / 10001.0;
//cout << p2 << endl;
for (j = 0; j < N * 2; j++)
{
if (DoubleQi[j] > p2)
{
Individual[i].fit = DoubleIndi[j].fit;
Individual[i].x1 = DoubleIndi[j].x1;
Individual[i].x2 = DoubleIndi[j].x2;
Individual[i].fitChange = DoubleIndi[i].fitChange;
for (int k = 0; k < 33; k++)
Individual[i].gene[k] = DoubleIndi[j].gene[k];
break;
}
}
}
//精英个体EliteGene[E][33]直接加入下一代 Individual[N][33]
for (j = 0; j < E; j++, i++)
{
for (int k = 0; k < 33; k++)
Individual[i].gene[k] = elite[j].gene[k];
Individual[i].fitChange = 1;
}
delete[]DoublePi;
delete[]DoubleQi;
delete[]DoubleIndi;
DoubleIndi = NULL;
}
//输出精英的适应值和基因码
void OutputElite(Elite elite[], int tnow, int Current_t)
{
cout << "种群第" << tnow << "次" << Current_t << "代最优精英个体的适应值:" << fixed << setprecision(15) << elite[0].fit;
cout << " 它的f(x1,x2)=(" << elite[0].x1 << "," << elite[0].x2 << ") 它的基因码:";
for (int j = 0; j < 33; j++)
{
cout << elite[0].gene[j];
}
cout << endl;
}
int main()
{
//创建随机数种子
srand((unsigned)time(NULL));
//声明N个个体
Population* Individual = new Population[N*2];
//声明E个精英
Elite* elite = new Elite[E];
//声明基因到x1,x2,fit的映射关系
GeneMappingFit* gmf = new GeneMappingFit[N*2];
//精英值第t次收敛成功的迭代次数数组Successful[T],成功收敛次数ST
int* Successful = new int[T]();
int ST = 0;
//执行T次观察遗传算法是否收敛到最佳值
for (int tnow = 0; tnow < T; tnow++)
{
//初始化种群
for (int Indi = 0; Indi < N; Indi++)
Individual[Indi].Initialize();
//迭代Times次
int Current_t = 0;
int output = 0;
for (; Current_t < Times; Current_t++)
{
//计算个体的表现型:
ComputeFit(Individual, gmf);
//保留E个适应度最高的精英:double Elite[E] ,以及它的基因型 int EliteGene[E][33]
Save(Individual, elite);
//输出当前代的精英表现形(适应值)以及基因型
//OutputElite(elite,tnow, Current_t);
//判断精英的基因是否为最佳38.85026,是则
if (elite[0].fit>38.8502926)
{
ST++;
Successful[tnow] = Current_t;
OutputElite(elite, tnow, Current_t);
output = 1;
break;
}
//轮盘赌选择创建交叉池 int Pool[N][33]
Population*pool=new Population[N];
CreatePool(Individual, pool);
//种群个体间基因在交叉池两点交叉以及单点变异 产生在交叉池中的子代 int Pool[N][33]
IndiCrossVariation(pool);
//把父代和子代合并,进行轮盘赌选择N-E个个体,更新种群个体 Individual[N-E][33]
UpdataPopulation(Individual, pool, elite, gmf);
delete[]pool;
pool = NULL;
}
if (output == 0)
OutputElite(elite, tnow, Current_t);
}
//计算种群收敛到最优的概率
cout << endl << "精英收敛到最佳值的次数:" << ST << " 概率为:" << ST * 1.0 / T << endl;
cout << "每次收敛的迭代次数:"<<endl;
for (int dt = 0, nt = 0; dt < T; dt++, nt++)
{
cout << Successful[dt] << ", ";
if (nt == 10)
{
cout << endl;
nt = 0;
}
}
delete[]Successful;
delete[]gmf;
gmf = NULL;
delete[]elite;
elite = NULL;
delete[]Individual;
Individual = NULL;
return 0;
}
更多推荐
c++ 遗传算法 记录
发布评论