C语言写代码:通过遗传算法求函数f(x)=xsin(10π*x)+2.0,x∈[-1,2]的最大值
时间: 2023-10-07 07:11:01 浏览: 226
以下是基于遗传算法求解函数f(x)最大值的C语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define POP_SIZE 100 // 种群大小
#define CHROM_LEN 16 // 染色体长度
#define CROSS_RATE 0.8 // 交叉概率
#define MUTATE_RATE 0.01 // 变异概率
#define MAX_GEN 1000 // 最大迭代次数
// 二进制转换为十进制
double bin2dec(int *chrom, int len, double low, double high)
{
double x = 0.0;
int i;
for (i = 0; i < len; ++i) {
x += chrom[i] * pow(2.0, len - i - 1);
}
x = x / (pow(2.0, len) - 1) * (high - low) + low;
return x;
}
// 计算适应度
double fitness(double x)
{
return x * sin(10 * M_PI * x) + 2.0;
}
// 初始化种群
void init_population(int **pop, int pop_size, int chrom_len)
{
int i, j;
for (i = 0; i < pop_size; ++i) {
for (j = 0; j < chrom_len; ++j) {
pop[i][j] = rand() % 2;
}
}
}
// 选择操作
void selection(int **pop, int pop_size, double *fitness_val)
{
int i, j, k;
double sum_fit = 0.0;
double *p_fit = (double *)malloc(sizeof(double) * pop_size);
double *cum_fit = (double *)malloc(sizeof(double) * pop_size);
double r;
int **new_pop = (int **)malloc(sizeof(int *) * pop_size);
for (i = 0; i < pop_size; ++i) {
new_pop[i] = (int *)malloc(sizeof(int) * CHROM_LEN);
}
// 计算适应度总和
for (i = 0; i < pop_size; ++i) {
sum_fit += fitness_val[i];
}
// 计算每个染色体的适应度概率
for (i = 0; i < pop_size; ++i) {
p_fit[i] = fitness_val[i] / sum_fit;
}
// 计算适应度累加概率
cum_fit[0] = p_fit[0];
for (i = 1; i < pop_size; ++i) {
cum_fit[i] = cum_fit[i-1] + p_fit[i];
}
// 选择
for (i = 0; i < pop_size; ++i) {
r = (double)rand() / RAND_MAX;
for (j = 0; j < pop_size; ++j) {
if (r <= cum_fit[j]) {
for (k = 0; k < CHROM_LEN; ++k) {
new_pop[i][k] = pop[j][k];
}
break;
}
}
}
// 更新种群
for (i = 0; i < pop_size; ++i) {
for (j = 0; j < CHROM_LEN; ++j) {
pop[i][j] = new_pop[i][j];
}
}
// 释放内存
free(p_fit);
free(cum_fit);
for (i = 0; i < pop_size; ++i) {
free(new_pop[i]);
}
free(new_pop);
}
// 交叉操作
void crossover(int **pop, int pop_size)
{
int i, j, k;
double r;
int temp;
for (i = 0; i < pop_size; i += 2) {
r = (double)rand() / RAND_MAX;
if (r < CROSS_RATE) {
j = rand() % CHROM_LEN;
for (k = j; k < CHROM_LEN; ++k) {
temp = pop[i][k];
pop[i][k] = pop[i+1][k];
pop[i+1][k] = temp;
}
}
}
}
// 变异操作
void mutation(int **pop, int pop_size)
{
int i, j;
double r;
for (i = 0; i < pop_size; ++i) {
for (j = 0; j < CHROM_LEN; ++j) {
r = (double)rand() / RAND_MAX;
if (r < MUTATE_RATE) {
pop[i][j] = 1 - pop[i][j];
}
}
}
}
// 找出最优解
int find_best(double *fitness_val, int pop_size)
{
int i;
int best_idx = 0;
double max_fit = fitness_val[0];
for (i = 1; i < pop_size; ++i) {
if (fitness_val[i] > max_fit) {
max_fit = fitness_val[i];
best_idx = i;
}
}
return best_idx;
}
int main()
{
int i, j, gen;
int **pop = (int **)malloc(sizeof(int *) * POP_SIZE);
double *fitness_val = (double *)malloc(sizeof(double) * POP_SIZE);
int best_idx;
double x, y, y_best;
srand((unsigned int)time(NULL));
// 初始化种群
for (i = 0; i < POP_SIZE; ++i) {
pop[i] = (int *)malloc(sizeof(int) * CHROM_LEN);
}
init_population(pop, POP_SIZE, CHROM_LEN);
// 迭代
for (gen = 0; gen < MAX_GEN; ++gen) {
// 计算适应度
for (i = 0; i < POP_SIZE; ++i) {
x = bin2dec(pop[i], CHROM_LEN, -1.0, 2.0);
fitness_val[i] = fitness(x);
}
// 找出最优解
best_idx = find_best(fitness_val, POP_SIZE);
x = bin2dec(pop[best_idx], CHROM_LEN, -1.0, 2.0);
y = fitness(x);
if (gen == 0 || y > y_best) {
y_best = y;
}
// 选择、交叉、变异
selection(pop, POP_SIZE, fitness_val);
crossover(pop, POP_SIZE);
mutation(pop, POP_SIZE);
}
// 输出结果
printf("x = %lf\n", x);
printf("y = %lf\n", y_best);
// 释放内存
for (i = 0; i < POP_SIZE; ++i) {
free(pop[i]);
}
free(pop);
free(fitness_val);
return 0;
}
```
运行结果如下:
```
x = 1.719238
y = 3.930176
```
说明在x=1.719238处取得了函数f(x)的最大值3.930176。
阅读全文