遗传算法求解函数最大值用例

学习遗传算法自己改了一个用例,感谢下面两篇文章的作者:

参考文章:http://blog.csdn.net/emiyasstar__/article/details/6938608

                 http://blog.csdn.net/chudongfang2015/article/details/51720607

/*************************************************************************
	> 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 <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <algorithm>

#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[group_num];

//在这里创建了多个种群,这样使得解更具有准确性。
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;
        }
   }
}










结果截图:

《遗传算法求解函数最大值用例》



    原文作者:遗传算法
    原文地址: https://blog.csdn.net/u010312436/article/details/51768673
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞