采用遗传算法求解最大值c语言,遗传算法求解函数最大值用例

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

/*************************************************************************

> 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;

}

}

}

结果截图:

0818b9ca8b590ca3270a3433284dd417.png



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值