学习遗传算法自己改了一个用例,感谢下面两篇文章的作者:
/*************************************************************************
> File Name: 袋鼠跳遗传算法求函数最大值.cpp
> Author:fanchenxin
> Mail:531266381@qq.com
> Created Time: 2016年06月24日 星期五
> problem: f(X) = X*sin(10*PI*X) + 2.0 ; X in [-1, 2] 求最大值及对应的X
先初始化随机点,相当于将很多的袋鼠放到山间,让他们
跳来跳去寻找最高的山峰,
************************************************************************/
#include
#include
#include
#include
#include
#include
#include
#define indiv_per_group (50) //一个种群中个体的数目
#define probability (60) //变异概率
#define genmax (100) //最大产生代数
#define group_num (100) //产生种群数量
#define mutation_step (0.005) //突变的步长
using namespace std;
#define PI (3.14159)
#define LEFT (-1)
#define RIGHT (2)
typedef enum
{
FALSE = 0,
TRUE = 1
}BOOL;
typedef struct individual //一个个体
{
double x; //x in [-1, 2] : 袋鼠所在的横向位置
double fx; //f(x)值:每个个体对环境的适应值,可以理解为袋鼠处在山峰的高度
int live; //标志这个个体是否还活着
}INDI;
typedef struct group//一个种群
{
INDI individuals[indiv_per_group]; //数组存储个体
INDI best; //最优个体
int best_gen; //最优个体所在的代数
int cur_gen; //种群当前的代数
}GROUP;
/* 计算适应值函数(也是我们需要求解的函数) */
double fx(double x)
{
return x * sin(10 * PI * x) + 2.0;
}
//1.初始化t←0进化代数计数器;genmax是最大进化代数;随机生成indiv_per_group个个体作为初始群体P(t);
void init();
//2.个体评价
void assess();
//3.选择运算 将选择算子作用于群体
void choose(int gen);
//4.交叉运算 将交叉算子作用于群体,保留较优个体,淘汰较差个体
void cross();
//5.变异运算 将变异算子作用于群体,并通过以上运算得到下一代群体p(t+1)
void mutation();
//总调用函数,决定一个种群的进化
void sovel();
//子模块
INDI cross_once(int father,int mother);
void mutation_one(int x);
//创建一个种群
GROUP Group;
//储存每个种群进化的结果
INDI bestsovel[105];
//在这里创建了多个种群,这样使得解更具有准确性。
int main(int argc,char *argv[])
{
//时间种子产生随机数
srand(time(0));
int i;
//对产生的种群进行一一求解
for(i = 0;i < group_num; i++)
{
sovel();
bestsovel[i]=Group.best;
}
printf("输出每个种群的最优解:\n");
//输出每个种群的最优个体(解)
for(i = 0; i < group_num; i++)
printf("%dth: x = %f, fx = %f \n",i, bestsovel[i].x, bestsovel[i].fx);
//排序,并输出所有种群的最优解
INDI t;
for(i = 0;i < group_num; i++)
{
for(int j = i; j < group_num; j++)
{
if(bestsovel[i].fx < bestsovel[j].fx)
{
t = bestsovel[i];
bestsovel[i] = bestsovel[j];
bestsovel[j] = t;
}
}
}
printf("所有种群的最优解:");
printf("x = %f, fx = %f \n", bestsovel[0].x, bestsovel[0].fx);
return 0;
}
//对一个种群进行求解。
void sovel()
{
init();
for(int i = 1;i <= genmax; i++) //种群繁杂代数
{
Group.cur_gen = i;
assess(); //评估,计算适应值
choose(Group.cur_gen); //找最优个体,淘汰较差个体
cross(); //交叉产生子个体
mutation(); //变异
}
}
void init()
{
Group.best.fx = -0xffffffff;//初始化一个很小的值,便于下面比较
Group.best_gen = 0;//记录产生最好结果的代数
Group.cur_gen = 0;//当前代数为0
//把一个种群中的每一个个体随机初始化
for(int j = 0; j < indiv_per_group; j++)
{
int t = rand() % 3001; /*产生0 ~3000 的随机数*/
double x = ((double)t / 1000) - 1; /* 产生-1~2的浮点数 */
Group.individuals[j].x = x;
Group.individuals[j].live = TRUE;
}
}
//个体评价
void assess()
{
//计算出每个个体的fx值
for(int i = 0; i < indiv_per_group; i++)
{
Group.individuals[i].fx = fx(Group.individuals[i].x);
}
}
/* 利用轮转盘法进行淘汰 */
void choose(int gen)
{
INDI t;
//使用轮转盘法进行淘汰
double totalFxValue = 0.0;
int i = 0;
for(i = 0; i < indiv_per_group; i++){
totalFxValue += Group.individuals[i].fx;
}
Group.best.fx = Group.individuals[0].fx;
Group.best.x = Group.individuals[0].x;
double tmp_add = 0;
for(i = 0; i < indiv_per_group; i++){
double t = rand() / double(RAND_MAX); /* 0 ~ 1 浮点数*/
tmp_add += Group.individuals[i].fx;
double tmp = tmp_add / totalFxValue; //累计概率
if(tmp >= t){
if(Group.individuals[i].fx > Group.best.fx){
Group.best.fx = Group.individuals[i].fx;
Group.best.x = Group.individuals[i].x;
}
continue;
}
else{
Group.individuals[i].live = FALSE; /* 淘汰掉 */
}
}
//选出这个种群的最优个体,并储存
if(Group.best.fx > Group.individuals[0].fx)
{
Group.best_gen = gen;
}
}
/* 随机挑选父母,并且取得他们横坐标之间的
随机数作为孩子的横坐标,并进行择优比较*/
void cross()
{
int first = 0, second = 0;
for(int j = 0; j < indiv_per_group; j++)
{
if(Group.individuals[j].live == FALSE){ /* 如果该个体已经被淘汰*/
/* 选择两个还活着的个体作为父母 */
while(1){
while(1){
first = rand() % indiv_per_group;
if(Group.individuals[first].live == TRUE)
break;
}
second = rand() % indiv_per_group;
if(Group.individuals[second].live == TRUE)
break;
}
/* 产生新个体 */
/* 取得Group.individuals[first].x 到Group.individuals[second].x之间的随机数 */
double diff = 0.0, tmp_x = 0.0;
if(Group.individuals[first].x > Group.individuals[second].x){
diff = Group.individuals[first].x - Group.individuals[second].x;
tmp_x = (rand() / double(RAND_MAX)) * diff; /* 0 ~ diff 浮点数*/
tmp_x += Group.individuals[second].x;
//printf("start:%f, end:%f, tmp_x: %f\n", Group.individuals[second].x,
//Group.individuals[first].x, tmp_x);
}else{
diff = Group.individuals[second].x - Group.individuals[second].x;
tmp_x = (rand() / double(RAND_MAX)) * diff; /* 0 ~ diff 浮点数*/
tmp_x += Group.individuals[first].x;
//printf("start:%f, end:%f, tmp_x: %f\n", Group.individuals[first].x,
//Group.individuals[second].x, tmp_x);
}
double tmp_fx = fx(tmp_x);
if(tmp_fx > Group.individuals[first].fx && tmp_fx > Group.individuals[second].fx){
Group.individuals[j].x = tmp_x;
Group.individuals[j].fx = tmp_fx;
}
else{
if(Group.individuals[first].fx > Group.individuals[second].fx){
Group.individuals[j].x = Group.individuals[first].x;
Group.individuals[j].fx = Group.individuals[first].fx;
}else{
Group.individuals[j].x = Group.individuals[second].x;
Group.individuals[j].fx = Group.individuals[second].fx;
}
}
Group.individuals[j].live = TRUE;
}
}
return;
}
//对一个种群的全部个体都进行变异运算
void mutation()
{
for(int i = 0;i < indiv_per_group; i++)
{
if(Group.individuals[i].live == TRUE){
mutation_one(i);
}
}
}
//对一个个体的变异运算
void mutation_one(int x)
{
int pro = rand() % 100;
if(pro > probability)
return ;
//用来判断变异是增加还是减少
double t = rand() / double(RAND_MAX); /* 0 ~ 1 浮点数*/
if(t > 0.5){
Group.individuals[x].x += mutation_step;
if(Group.individuals[x].x > RIGHT)
Group.individuals[x].x = LEFT;
Group.individuals[x].fx = fx(Group.individuals[x].x);
if(Group.individuals[x].fx > Group.best.fx){
Group.best.fx = Group.individuals[x].fx;
Group.best.x = Group.individuals[x].x;
}
}else{
Group.individuals[x].x -= mutation_step;
if(Group.individuals[x].x < LEFT)
Group.individuals[x].x = RIGHT;
Group.individuals[x].fx = fx(Group.individuals[x].x);
if(Group.individuals[x].fx > Group.best.fx){
Group.best.fx = Group.individuals[x].fx;
Group.best.x = Group.individuals[x].x;
}
}
}
结果截图: