利用遗传算法求解函数最大值并使用c写一个简易的示例代码
遗传算法是一种模拟自然界进化过程的算法,适用于求解优化问题。具体步骤如下:
-
初始化种群:随机生成一定数量的个体作为初始种群。
-
评估个体适应度:将每个个体代入目标函数中计算适应度,评估个体的优劣。
-
选择个体:根据适应度大小选择优秀的个体,较优秀的个体有更大的概率被选择。
-
交叉繁殖:从选择的个体中随机选择两个个体进行交叉繁殖,生成新的个体。
-
变异:对新生成的个体进行变异操作,增加种群的多样性。
-
重复步骤2-5,直到达到停止条件。
以下是一个简单的使用遗传算法求解函数最大值的示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define POP_SIZE 100 // 种群大小
#define GEN_MAX 1000 // 迭代次数
#define MUTATION_RATE 0.01 // 变异率
// 目标函数
double fitness(double x) {
return sin(x) + sin(10.0/3.0*x);
}
// 随机生成初始种群
void init_pop(double pop[][2], double lower, double upper) {
int i;
for (i = 0; i < POP_SIZE; i++) {
pop[i][0] = (double)rand()/(double)RAND_MAX*(upper-lower) + lower;
pop[i][1] = fitness(pop[i][0]);
}
}
// 选择个体
void selection(double pop[][2], double new_pop[][2]) {
int i, j, k, r1, r2;
double sum_fitness = 0.0, cum_fitness = 0.0, p;
double fitness[POP_SIZE];
for (i = 0; i < POP_SIZE; i++) {
sum_fitness += pop[i][1];
fitness[i] = pop[i][1];
}
for (i = 0; i < POP_SIZE; i++) {
p = (double)rand()/(double)RAND_MAX;
for (j = 0; j < POP_SIZE; j++) {
cum_fitness += fitness[j]/sum_fitness;
if (p <= cum_fitness) {
for (k = 0; k < 2; k++) {
new_pop[i][k] = pop[j][k];
}
cum_fitness = 0.0;
break;
}
}
}
}
// 交叉繁殖
void crossover(double new_pop[][2]) {
int i, j, k;
double p;
for (i = 0; i < POP_SIZE; i++) {
p = (double)rand()/(double)RAND_MAX;
if (p < 0.7) {
j = rand() % POP_SIZE;
while (j == i) {
j = rand() % POP_SIZE;
}
p = (double)rand()/(double)RAND_MAX;
if (p < 0.5) {
for (k = 0; k < 2; k++) {
new_pop[i][k] = new_pop[i][k] + 0.5*(new_pop[j][k]-new_pop[i][k]);
new_pop[j][k] = new_pop[j][k] + 0.5*(new_pop[i][k]-new_pop[j][k]);
}
}
else {
for (k = 0; k < 2; k++) {
new_pop[i][k] = new_pop[i][k] - 0.5*(new_pop[j][k]-new_pop[i][k]);
new_pop[j][k] = new_pop[j][k] - 0.5*(new_pop[i][k]-new_pop[j][k]);
}
}
}
}
}
// 变异
void mutation(double new_pop[][2], double lower, double upper) {
int i, j;
double p;
for (i = 0; i < POP_SIZE; i++) {
p = (double)rand()/(double)RAND_MAX;
if (p < MUTATION_RATE) {
j = rand() % 2;
new_pop[i][j] = (double)rand()/(double)RAND_MAX*(upper-lower) + lower;
new_pop[i][1] = fitness(new_pop[i][0]);
}
}
}
// 寻找最优个体
int find_best(double pop[][2]) {
int i, best_idx = 0;
double best_fitness = pop[0][1];
for (i = 1; i < POP_SIZE; i++) {
if (pop[i][1] > best_fitness) {
best_fitness = pop[i][1];
best_idx = i;
}
}
return best_idx;
}
int main() {
int i, gen, best_idx;
double pop[POP_SIZE][2], new_pop[POP_SIZE][2];
double lower = -10.0, upper = 10.0;
srand(time(NULL));
init_pop(pop, lower, upper);
for (gen = 0; gen < GEN_MAX; gen++) {
selection(pop, new_pop);
crossover(new_pop);
mutation(new_pop, lower, upper);
for (i = 0; i < POP_SIZE; i++) {
for (int j = 0; j < 2; j++) {
pop[i][j] = new_pop[i][j];
}
}
best_idx = find_best(pop);
printf("generation: %d, x = %f, f(x) = %f\n", gen, pop[best_idx][0], pop[best_idx][1]);
}
best_idx = find_best(pop);
printf("Best solution: x = %f, f(x) = %f\n", pop[best_idx][0], pop[best_idx][1]);
return 0;
}
该程序使用了遗传算法求解函数 $f(x) = \sin(x) + \sin(\frac{10}{3}x)$ 在区间 $[-10,10]$ 的最大值。程序中,种群大小为100,迭代次数为1000,变异率为0.01。在每次迭代中,选择、交叉、变异操作后,计算最优个体的适应度,并输出当前迭代次数、最优个体的自变量和函数值。最终输出最优解的自变量和函数值
原文地址: https://www.cveoy.top/t/topic/e8Yy 著作权归作者所有。请勿转载和采集!