人工智能实验-使用遗传算法求函数最值

完整代码:

#include 

#define indiv_per_group    (50) //一个种群中个体的数目
#define probability (60) //变异概率
#define genmax      (100) //最大产生代数

using namespace std;
typedef struct indi //一个个体
{
    int x;           //x in [0, 30] : 横向位置
    char bi[5];        //二进制编码,长度为5
    int fx;         //f(x)值:每个个体对环境的适应值,即当前函数值
    bool live;            //标志这个个体是否还活着
}INDI;


typedef struct group//一个种群
{
    INDI individuals[indiv_per_group]; //数组存储个体
    INDI best;            //最优个体
    int  best_gen;        //最优个体所在的代数
    int  cur_gen;         //种群当前的代数
}GROUP;

/* 计算适应值函数(也是我们需要求解的函数) */
int fx(int x)
{
    return x*x*x-60*x*x+900*x+100;
}

GROUP Group;
char *stop;

//1.初始化:随机产生5位二进制数
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() % 100;   /*产生0 ~100 的随机数*/
        for(int k=0;k<5;k++)
        {
            if(t>50)
                Group.individuals[j].bi[k]=1;
            else
                Group.individuals[j].bi[k]=0;
        }

        Group.individuals[j].x = strtol(Group.individuals[j].bi,&stop,2);
        Group.individuals[j].live = true;
    }
}

//2.个体评价:得到每个个体的适应度
void assess()
{
    //计算出每个个体的fx值
    for(int i = 0; i < indiv_per_group; i++)
    {
        Group.individuals[i].fx = fx(Group.individuals[i].x);
    }
}

//3.选择运算:使用轮转盘法进行选择与淘汰
void choose(int gen)
{
    //使用轮转盘法进行淘汰
    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;
                for(int k=0;k<5;k++)
                    Group.best.bi[k]=Group.individuals[i].bi[k];
            }
            continue;
        }
        else{
            Group.individuals[i].live = false; /* 淘汰掉 */
        }
    }

    //选出这个种群的最优个体,并储存
    if(Group.best.fx > Group.individuals[0].fx)
    {
        Group.best_gen = gen;
    }
}


//4.交叉运算:单点交叉
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;
            }

            char str[5];
            for(int k=0;k<3;k++)
                str[k]=Group.individuals[first].bi[k];
            for(int k=3;k<5;k++)
                str[k]=Group.individuals[second].bi[k];
            int new_x=strtol(str,&stop,2);
            int new_fx=fx(new_x);
            if(new_fx>Group.individuals[first].fx && new_fx > Group.individuals[second].fx)
            {
                Group.individuals[j].x = new_x;
                Group.individuals[j].fx = new_fx;
                for(int k=0;k<5;k++)
                    Group.individuals[j].bi[k]=str[k];
            }
            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;
                    for(int k=0;k<5;k++)
                        Group.individuals[j].bi[k]=Group.individuals[first].bi[k];
                }else{
                    Group.individuals[j].x = Group.individuals[second].x;
                    Group.individuals[j].fx = Group.individuals[second].fx;
                    for(int k=0;k<5;k++)
                        Group.individuals[j].bi[k]=Group.individuals[second].bi[k];
                }
            }
            Group.individuals[j].live = true;
        }
    }
    return;
}

//5.变异运算 :位点变异——随机每个位置50%几率取反
//对一个个体的变异运算
void mutation_one(int x)
{
    int pro = rand() % 100;
    if(pro > probability)
        return ;

    for(int k=0;k<5;k++)
    {
        int t=rand()%100;
        if(t>50)
        {
            if(Group.individuals[x].bi[k]=='1')
                Group.individuals[x].bi[k]='0';
            else
                Group.individuals[x].bi[k]='1';
        }
            Group.individuals[x].bi[k]^=1;
    }
    Group.individuals[x].x=strtol(Group.individuals[x].bi,&stop,2);
    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;
        for(int k=0;k<5;k++)
            Group.best.bi[k]=Group.individuals[x].bi[k];
    }
}


//对一个种群的全部个体都进行变异运算
void mutation()
{
    for(int i = 0;i < indiv_per_group; i++)
    {
        if(Group.individuals[i].live == true){
            mutation_one(i);
        }
    }
}

//总调用函数,决定一个种群的进化
//对一个种群进行求解。
void sovel()
{
    init();
    for(int  i = 1;i <= genmax; i++) //种群繁杂代数
    {
        Group.cur_gen = i;
        assess();               //评估,计算适应值
        choose(Group.cur_gen);  //找最优个体,淘汰较差个体
        cross();                //交叉产生子个体
        mutation();             //变异
    }
}

int main()
{
    //时间种子产生随机数
    srand(time(0));
    sovel();
    cout<

实验结果:

人工智能实验-使用遗传算法求函数最值_第1张图片

你可能感兴趣的:(人工智能)