C++遗传算法求解函数y=xsin(10xπ)+2在区间[-1,2]上的最大值
C++遗传算法求解函数y=xsin(10xπ)+2在区间[-1,2]上的最大值
本文将利用C++实现遗传算法,寻找函数 y = x * sin(10 * x * π) + 2 在区间 [-1, 2] 上的最大值。
1. 问题分析
我们需要找到函数在给定区间内的最大值。传统的求解方法可能需要复杂的数学推导,而遗传算法提供了一种简单直观的解决方案。
2. 遗传算法设计
2.1 个体结构设计c++#define size 22 // 基因长度
struct Point { int x[size]; // 基因编码,每个基因代表解的一个分量 double fitness; // 适应度值,代表解的优劣};
每个个体用一个结构体 Point 表示,其中 x 数组表示个体的基因编码,fitness 表示个体的适应度值。
2.2 种群设计c++#define row 20 // 种群行数#define col 20 // 种群列数
struct GASet { Point obj[row][col]; // 种群,二维数组存储个体};
种群用一个结构体 GASet 表示,其中 obj 是一个二维数组,存储了所有的个体。
2.3 遗传算子
- 初始化: 随机生成初始种群,每个基因随机取0或1。* 解码: 将二进制基因序列转换为区间 [-1, 2] 内的实数。* 适应度计算: 计算每个个体的适应度值,这里直接使用函数值作为适应度值。* 选择: 使用轮盘赌选择算法,选择适应度值高的个体进行交叉和变异操作。* 交叉: 使用单点交叉算子,将两个父代个体的部分基因进行交换,产生新的子代个体。* 变异: 使用位翻转变异算子,将个体中的某个基因进行翻转,增加种群的多样性。
3. 代码实现c++#include <stdio.h>#include <stdlib.h>#include <math.h>#include <time.h>
#define size 22#define xmax 2.0#define xmin -1.0#define row 20#define col 20#define PI 3.141592653589
typedef struct Point Point;
// 个体结构体struct Point { int x[size]; // 基因编码 double fitness; // 适应度值};
// 种群结构体struct GASet { Point obj[row][col];};
// 初始化个体void init(struct Point *a) { for (int i = 0; i < size; i++) { a->x[i] = rand() % 2; }}
// 解码double decode(struct Point *a) { double y = 0; for (int i = 0; i < size; i++) { y += a->x[i] * pow(2.0, size - i - 1); } y = xmin + y * (xmax - xmin) / (pow(2.0, size) - 1); return y;}
// 计算适应度值double getFitness(struct Point *a) { double vx = decode(a); a->fitness = vx * sin(10 * PI * vx) + 2.0; return a->fitness;}
// 交换两个个体void swap(Point *a, Point *b) { Point temp = *a; *a = *b; *b = temp;}
// 交叉算子void cross(Point *a, Point *b, Point *ab, Point *ba) { int pos = rand() % size; for (int i = 0; i < pos; i++) { ab->x[i] = a->x[i]; ba->x[i] = b->x[i]; } for (int i = pos; i < size; i++) { ab->x[i] = b->x[i]; ba->x[i] = a->x[i]; }}
// 变异算子void mut(Point *a) { int pos = rand() % size; a->x[pos] = (a->x[pos] + 1) % 2;}
// 寻优移位算子void findBestMove(GASet *p) { for (int i = 0; i < row; i++) { int pos = 0; double max = p->obj[i][pos].fitness; for (int j = 1; j < col; j++) { if (max < p->obj[i][j].fitness) { pos = j; max = p->obj[i][j].fitness; } } swap(&(p->obj[i][0]), &(p->obj[i][pos])); }}
// 初始化种群void initSet(GASet *p) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { init(&(p->obj[i][j])); } }}
// 计算种群适应度值void calSet(GASet *p) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { getFitness(&(p->obj[i][j])); } }}
// 种群演化void evol(GASet *p) { // 寻优移位 findBestMove(p); // 交叉 for (int i = 0; i < row; i++) { for (int j = i + 1; j < col; j++) { cross(&(p->obj[i][0]), &(p->obj[j][0]), &(p->obj[i][j]), &(p->obj[j][i])); } } // 变异 for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { mut(&(p->obj[i][j])); } } // 计算适应度值 calSet(p);}
// 获取最优个体位置int getGbest(GASet *p) { int pos = 0; double max = p->obj[pos][pos].fitness; for (int i = 1; i < row; i++) { if (max < p->obj[i][i].fitness) { pos = i; max = p->obj[i][i].fitness; } } return pos;}
int main() { srand(time(0));
GASet p; initSet(&p); calSet(&p);
int n = 0; while (n < 200) { evol(&p); n++; }
int best = getGbest(&p); printf('最优解的x值为: %0.8f
', decode(&(p.obj[best][best]))); printf('最优解的函数值为: %0.8f ', (p.obj[best][best]).fitness);
return 0
原文地址: https://www.cveoy.top/t/topic/eEOk 著作权归作者所有。请勿转载和采集!