1、遗传算法求函数最优解

题目要求:
f(x1,x2) = 21.5+x1*sin(4pi*x1)+x2*sin(20pi*x2)

st:约束范围
x1:[-3.0,12.1]
x2:[4.1,5.8]
求函数在约束范围内的最大值

2、算法流程图:

3、Genetic.h文件

#ifndef _GENETIC_H_
#define _GENETIC_H_using namespace std;#define  PI    3.14159265358979323846//遗传算法参数,种群规模(0~100)、繁殖代数、函数变量个数、交叉概率、编译概率
# define GROUP_SCALE    50
# define MAX_GENS       500
# define N_VARS         2
# define P_MATING       0.8
# define P_MUTATION     0.15struct Individual
{double Xn[N_VARS];      //存放变量值double Fitness;         //适应值double ReFitness;       //适应值概率密度double SumFitness;      //累加分布,为轮盘转
};
struct X_Range
{double Upper;           //变量的上界取值double Lower;           //变量的下界取值
};template<typename T>
T randT(T Lower, T Upper); //产生任意类型随机数函数void crossover(int &seed);
void elitist();        //基因保留
void evaluate();void initGroup(int &seed);void selectBest();
void mutate(int &seed);double r8_uniform_ab(double a, double b, int &seed);
int i4_uniform_ab(int a, int b, int &seed);void report(int Xnration);
void selector(int &seed);
void showTime();
void Xover(int one, int two, int &seed);
#endif // !_GENETIC_H_

4、Genetic.cpp

# include <cstdlib>
# include <iostream>
# include <iomanip>
# include <fstream>
# include <iomanip>
# include <cmath>
# include <ctime>
# include <cstring>
#include "Genetic.h"//申请种群内存,其中多加1个是放置上一代中最优秀个体
struct Individual Population[GROUP_SCALE + 1];   X_Range  XnRange[N_VARS] = { { -3.0,12.1}, {4.1,5.8} };//有交配权的所有父代进行交叉
void crossover(int &seed)
{const double a = 0.0;const double b = 1.0;int mem;int one;int first = 0;double x;for (mem = 0; mem < GROUP_SCALE; ++mem){x = randT(0.0,1.0);//x = r8_uniform_ab(a, b, seed);//产生交配概率if (x < P_MATING){++first;if (first % 2 == 0)//交配{Xover(one, mem, seed);}else{one = mem;}}}return;
}//对最差的一代和最优的一代的处理,起到优化的目的
void elitist()
{int i;double best;int best_mem;double worst;int worst_mem;best = Population[0].Fitness;worst = Population[0].Fitness;for (i = 0; i < GROUP_SCALE - 1; ++i){if (Population[i + 1].Fitness < Population[i].Fitness){if (best <= Population[i].Fitness){best = Population[i].Fitness;best_mem = i;}if (Population[i + 1].Fitness <= worst){worst = Population[i + 1].Fitness;worst_mem = i + 1;}}else{if (Population[i].Fitness <= worst){worst = Population[i].Fitness;worst_mem = i;}if (best <= Population[i + 1].Fitness){best = Population[i + 1].Fitness;best_mem = i + 1;}}}//对于当前代的最优值的处理,如果当前的最优值小于上一代则将上一代的值最优个体取代当前的最弱个体
//基因保留if (Population[GROUP_SCALE].Fitness <= best){for (i = 0; i < N_VARS; i++){Population[GROUP_SCALE].Xn[i] = Population[best_mem].Xn[i];}Population[GROUP_SCALE].Fitness = Population[best_mem].Fitness;}else{for (i = 0; i < N_VARS; i++){Population[worst_mem].Xn[i] = Population[GROUP_SCALE].Xn[i];}Population[worst_mem].Fitness = Population[GROUP_SCALE].Fitness;}return;
}
//计算适应度值
void evaluate()
{int member;int i;double x[N_VARS + 1];for (member = 0; member < GROUP_SCALE; member++){for (i = 0; i < N_VARS; i++){x[i + 1] = Population[member].Xn[i];}Population[member].Fitness = 21.5 + x[1] * sin(4 * PI*x[1]) + x[2] * sin(20 * PI*x[2]);}return;
}//产生整形的随机数
int i4_uniform_ab(int a, int b, int &seed)
{int c;const int i4_huge = 2147483647;int k;float r;int value;if (seed == 0){cerr << "\n";cerr << "I4_UNIFORM_AB - Fatal error!\n";cerr << "  Input value of SEED = 0.\n";exit(1);}//保证a小于bif (b < a){c = a;a = b;b = c;}k = seed / 127773;seed = 16807 * (seed - k * 127773) - k * 2836;if (seed < 0){seed = seed + i4_huge;}r = (float)(seed)* 4.656612875E-10;////  Scale R to lie between A-0.5 and B+0.5.//r = (1.0 - r) * ((float)a - 0.5)+ r   * ((float)b + 0.5);////  Use rounding to convert R to an integer between A and B.//value = round(r);//四舍五入//保证取值不越界if (value < a){value = a;}if (b < value){value = b;}return value;
}//初始化种群个体
void initGroup(int &seed){int i;int j;double lbound;double ubound;// //  initGroup variables within the bounds //for (i = 0; i < N_VARS; i++){//input >> lbound >> ubound;for (j = 0; j < GROUP_SCALE; j++){Population[j].Fitness = 0;Population[j].ReFitness = 0;Population[j].SumFitness = 0;Population[j].Xn[i] = randT(XnRange[i].Lower, XnRange[i].Upper);//Population[j].Xn[i] = r8_uniform_ab(XnRange[i].Lower, XnRange[i].Upper, seed);}}return;
}//挑选出最大值,保存在种群数组的最后一个位置
void selectBest()
{int cur_best;int mem;int i;cur_best = 0;for (mem = 0; mem < GROUP_SCALE; mem++){if (Population[GROUP_SCALE].Fitness < Population[mem].Fitness){cur_best = mem;Population[GROUP_SCALE].Fitness = Population[mem].Fitness;}}for (i = 0; i < N_VARS; i++){Population[GROUP_SCALE].Xn[i] = Population[cur_best].Xn[i];}return;
}//个体变异
void mutate(int &seed)
{const double a = 0.0;const double b = 1.0;int i;int j;double lbound;double ubound;double x;for (i = 0; i < GROUP_SCALE; i++){for (j = 0; j < N_VARS; j++){//x = r8_uniform_ab(a, b, seed);x = randT(a, b);//突变概率if (x < P_MUTATION){lbound = XnRange[j].Lower;ubound = XnRange[j].Upper;Population[i].Xn[j] = randT(lbound, ubound);//Population[i].Xn[j] = r8_uniform_ab(lbound, ubound, seed);}}}return;
}//模板函数,用于生成各种区间上的数据类型
template<typename T>
T randT(T Lower, T Upper)
{return rand() / (double)RAND_MAX *(Upper - Lower) + Lower;
}//产生小数随机数
double r8_uniform_ab(double a, double b, int &seed){int i4_huge = 2147483647;int k;double value;if (seed == 0){cerr << "\n";cerr << "R8_UNIFORM_AB - Fatal error!\n";cerr << "  Input value of SEED = 0.\n";exit(1);}k = seed / 127773;seed = 16807 * (seed - k * 127773) - k * 2836;if (seed < 0){seed = seed + i4_huge;}value = (double)(seed)* 4.656612875E-10;value = a + (b - a) * value;return value;
}//输出每一代进化的结果
void report(int Xnration)
{double avg;double best_val;int i;double square_sum;double stddev;double sum;double sum_square;if (Xnration == 0){cout << "\n";cout << "  Xnration       Best            Average       Standard \n";cout << "  number           value           Fitness       deviation \n";cout << "\n";}sum = 0.0;sum_square = 0.0;for (i = 0; i < GROUP_SCALE; i++){sum = sum + Population[i].Fitness;sum_square = sum_square + Population[i].Fitness * Population[i].Fitness;}avg = sum / (double)GROUP_SCALE;square_sum = avg * avg * GROUP_SCALE;stddev = sqrt((sum_square - square_sum) / (GROUP_SCALE - 1));best_val = Population[GROUP_SCALE].Fitness;cout << "  " << setw(8) << Xnration<< "  " << setw(14) << best_val<< "  " << setw(14) << avg<< "  " << setw(14) << stddev << "\n";return;
}//选择有交配权的父代
void selector(int &seed)
{struct Individual NewPopulation[GROUP_SCALE + 1];//临时存放挑选的后代个体const double a = 0.0;const double b = 1.0;int i;int j;int mem;double p;double sum;sum = 0.0;for (mem = 0; mem < GROUP_SCALE; mem++){sum = sum + Population[mem].Fitness;}//计算概率密度for (mem = 0; mem < GROUP_SCALE; mem++){Population[mem].ReFitness = Population[mem].Fitness / sum;}// 计算累加分布,思想是轮盘法Population[0].SumFitness = Population[0].ReFitness;for (mem = 1; mem < GROUP_SCALE; mem++){Population[mem].SumFitness = Population[mem - 1].SumFitness +Population[mem].ReFitness;}// 选择个体为下一代繁殖,选择优秀的可能性大,这是轮盘法的奥秘之处for (i = 0; i < GROUP_SCALE; i++){p = r8_uniform_ab(a, b, seed);if (p < Population[0].SumFitness){NewPopulation[i] = Population[0];}else{for (j = 0; j < GROUP_SCALE; j++){if (Population[j].SumFitness <= p && p < Population[j + 1].SumFitness){NewPopulation[i] = Population[j + 1];}}}}//更新后代个体 for (i = 0; i < GROUP_SCALE; i++){Population[i] = NewPopulation[i];}return;
}//显示系统时间
void showTime()
{
# define TIME_SIZE 40static char time_buffer[TIME_SIZE];const struct tm *tm;size_t len;time_t now;now = time(NULL);tm = localtime(&now);len = strftime(time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm);cout << time_buffer << "\n";return;
# undef TIME_SIZE
}//交叉产生子代
void Xover(int one, int two, int &seed)
{int i;int point;double t;//随机选择交叉点,这里的点是以变量的整个长度为单位point = randT<int>(0, N_VARS - 1);//point = i4_uniform_ab(0, N_VARS - 1, seed);//交叉for (i = 0; i < point; i++){t = Population[one].Xn[i];Population[one].Xn[i] = Population[two].Xn[i];Population[two].Xn[i] = t;}return;
}

5、main.cpp

#include <iostream>
#include "Genetic.h"extern Individual Population[GROUP_SCALE + 1];int main()
{int Xnration;int i;int seed = 123456789;showTime();initGroup(seed);evaluate();selectBest();for (Xnration = 0; Xnration < MAX_GENS; Xnration++){selector(seed);crossover(seed);mutate(seed);report(Xnration);evaluate();elitist();}cout << "\n";cout << "  Best member after " << MAX_GENS << " Xnrations:\n";cout << "\n";for (i = 0; i < N_VARS; i++){cout << "  X(" << i + 1 << ") = " << Population[GROUP_SCALE].Xn[i] << "\n";}cout << "\n";cout << "  Best Fitness = " << Population[GROUP_SCALE].Fitness << "\n";showTime();while (1);return 0;
}

6、运行平台VS2013,500代迭加之后结果如下:

函数f(x1,x2)在x1=11.6249和x2=5.7268取得优解值: 38.8153

7、总结
遗传算法看似随机,但背后却是非随机的,是随机中朝最优解的一种策略。其过程有做了保证朝优值的方向的策略,一个是变异,另外一个是基因保留。不断的可以保证种群朝着最优方向进化。同时遗传算法的适应度函数的设计要求通常需要满足单值、连续、非负、最大化、计算量小、通用性强,因此适应度函数的设计需要根据结合实际的问题本身的特点而定。
遗传算法设计的几个关键参数:种群规模、交配率、变异率、进化代数;这几个参数的设计对函数的最终收敛性有着关系。

8、代码参考设计
http://people.sc.fsu.edu/~jburkardt/cpp_src/simple_ga/simple_ga.html

遗传算法GA算法思路及其C++实现相关推荐

  1. 基于遗传算法GA算法优化BP神经网络(Python代码实现)

    一. 概述 BP-GA算法的设计︰基于遗传算法的BP神经网络算法(以下简称BP-GA)就是在BP神经网络的学习过程中,将权重和阀值描述为染色体,并选取适宜的适应函数,然后进行GA迭代,直到某种意义上的 ...

  2. 【优化算法】遗传算法GA求解混合流水车间调度问题(附C++代码)

    [优化算法]遗传算法GA求解混合流水车间调度问题(附C++代码) 00 前言 各位读者大家好,好久没有介绍算法的推文了,感觉愧对了读者们热爱学习的心灵.于是,今天我们带来了一个神奇的优化算法--遗传算 ...

  3. MATLAB遗传算法GA求解TSP旅行商问题,可选PMX交叉、OX交叉及其它多种交叉方式,在算法中引入2-opt变异算子

    MATLAB遗传算法GA求解TSP旅行商问题,可选PMX交叉.OX交叉及其它多种交叉方式,在算法中引入2-opt变异算子.进化逆转算子提高算法局部搜索能力,利用国际通用的TSPLIB数据集中的eil5 ...

  4. 计算机视觉与深度学习 | 粒子群算法与遗传算法(GA)及与蚁群算法(ACO)比较

    ================================================ 博主github:https://github.com/MichaelBeechan 博主CSDN:h ...

  5. 使用GA算法解决TSP问题

    源代码传送门 文章目录 Genetic Algorithm 导言 GA算法流程 初始化种群 个体适应度计算 选择 交叉 变异 效果 总结 遗传算法的优化思路 GA与SA的比较 Genetic Algo ...

  6. GA遗传算法c语言,遗传算法GA(Genetic Algorithm)入门知识梳理

    一.遗传算法进化论背景知识 作为遗传算法生物背景的介绍,下面内容了解即可: 种群(Population):生物的进化以群体的形式进行,这样的一个群体称为种群. 个体:组成种群的单个生物. 基因 ( G ...

  7. 遗传算法(GA)入门知识梳理(超详细)

    目录 一.遗传算法的生物背景 二.遗传算法(GA)思想 2.1遗传算法的组成 2.2编码 2.3适应度函数 2.4遗传算子 2.4 运行参数 三.基本遗传算法(SGA)伪代码 3.1算法流程图 3.2 ...

  8. 用GA算法设计22个地点之间最短旅程-R语言实现

    数据挖掘入门与实战  公众号: datadw 相关帖子 转载︱案例 基于贪心算法的特征选择 用GA算法设计22个地点之间最短旅程-R语言实现 ----------------------------- ...

  9. 连续环境下基于enhanced GA算法的多目标多机器人路径算法

    10.1016/j.eswa.2018.08.008 https://doi.org/10.1016/j.eswa.2018.08.008 Abstract 连续环境多机器人路径规划,基于多种方法结合 ...

最新文章

  1. SilverLight 双向绑定
  2. Java Web - EL表达式和JSTL标签库
  3. logback输出日志到sentry
  4. 如何通过JavaScript动态加载js
  5. android开发(49) android 使用 CollapsingToolbarLayout ,可折叠的顶部导航栏
  6. 常见web攻击方式与防御方法
  7. Security+认证学习/备考经验
  8. SOME/IP不等同于SOA,CommonAPI-RPC通信和vsomeip基于消息通信
  9. python批量下载文件
  10. CSND Markdown语法学习笔记
  11. .NET Core使用微软官方类库实现汉字简繁切换以及转拼音
  12. 倾斜摄影的单体化建模研究 和osg 关系
  13. 【蓝桥杯算法模板题--蓝桥题库Java】
  14. 华为手机日历倒计时_倒计时软件app哪个好 苹果倒计时软件推荐
  15. android 蓝牙触控笔,FiftyThree 53 Paper pencil 电容笔蓝牙触控笔 上手试用
  16. 分布式存储系统-Ceph简单分析
  17. Milky都能学会的C#编程(一)——编程是啥?可以吃吗?
  18. Camstar MES 5.8 發現Ajax事件失效
  19. 乳酪gi_Windows 8生产力:谁动了我的奶酪? 哦,是的。
  20. linux改开机图片,修改linux开机启动图像

热门文章

  1. STM32F103ZET6---【硬件篇】ADC
  2. java过滤xss_java处理XSS过滤的方法
  3. linux开启rdp服务,让windows电脑mstsc远程,linux rdesktop远程windows机器
  4. 搭建自己的frp服务器
  5. pytorch 高光谱图像分类
  6. 防火墙、WAF、IPS、IDS、堡垒机的区别
  7. 回归里出现双峰的解决办法
  8. 【语义分割】一文概览主要语义分割网络,FCN、UNet、SegNet、DeepLab
  9. GitHub网站的主题设置
  10. eclipse打开报错