遗传算法求解函数最大值:C语言示例代码
遗传算法是一种优化算法,通常用于解决函数最大值或最小值的问题。其基本思想是模拟生物进化的过程,通过选择、交叉和变异等操作来不断改进种群,最终找到最优解。
下面是一个使用遗传算法求解函数最大值的示例代码(使用 C 语言实现):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define POPULATION_SIZE 100 // 种群大小
#define GENERATION_LIMIT 1000 // 迭代次数限制
#define MUTATION_RATE 0.01 // 变异概率
#define CROSSOVER_RATE 0.8 // 交叉概率
#define ELITISM 1 // 精英策略
double f(double x) // 待求解的函数
{
return x * x - 4 * x + 3;
}
typedef struct {
double x; // 染色体表示的解
double fitness; // 适应度
} Individual;
Individual population[POPULATION_SIZE];
double best_solution = 0;
double best_fitness = 0;
double random_double(double min, double max) // 生成指定范围内的随机数
{
return (double)rand() / RAND_MAX * (max - min) + min;
}
double calculate_fitness(double x) // 计算适应度
{
return f(x);
}
void initialize_population() // 初始化种群
{
for (int i = 0; i < POPULATION_SIZE; i++) {
population[i].x = random_double(-10, 10);
population[i].fitness = calculate_fitness(population[i].x);
}
}
void evaluate_population() // 评估种群
{
double sum_fitness = 0;
for (int i = 0; i < POPULATION_SIZE; i++) {
population[i].fitness = calculate_fitness(population[i].x);
sum_fitness += population[i].fitness;
if (population[i].fitness > best_fitness) {
best_fitness = population[i].fitness;
best_solution = population[i].x;
}
}
printf("Best solution: %lf, Best fitness: %lf\n", best_solution, best_fitness);
}
void select_parents(int* parent1, int* parent2) // 选择父母
{
double sum_fitness = 0;
for (int i = 0; i < POPULATION_SIZE; i++) {
sum_fitness += population[i].fitness;
}
double r1 = random_double(0, sum_fitness);
double r2 = random_double(0, sum_fitness);
double tmp_sum = 0;
for (int i = 0; i < POPULATION_SIZE; i++) {
tmp_sum += population[i].fitness;
if (tmp_sum >= r1) {
*parent1 = i;
break;
}
}
tmp_sum = 0;
for (int i = 0; i < POPULATION_SIZE; i++) {
tmp_sum += population[i].fitness;
if (tmp_sum >= r2) {
*parent2 = i;
break;
}
}
}
void crossover(int parent1, int parent2, Individual* child1, Individual* child2) // 交叉
{
double r = random_double(0, 1);
if (r < CROSSOVER_RATE) {
double alpha = random_double(0, 1);
child1->x = alpha * population[parent1].x + (1 - alpha) * population[parent2].x;
child2->x = (1 - alpha) * population[parent1].x + alpha * population[parent2].x;
} else {
child1->x = population[parent1].x;
child2->x = population[parent2].x;
}
}
void mutate(Individual* individual) // 变异
{
double r = random_double(0, 1);
if (r < MUTATION_RATE) {
double delta = random_double(-0.1, 0.1);
individual->x += delta;
}
}
void evolve() // 进化
{
Individual new_population[POPULATION_SIZE];
for (int i = 0; i < ELITISM; i++) { // 精英策略
new_population[i] = population[i];
}
for (int i = ELITISM; i < POPULATION_SIZE; i += 2) { // 产生下一代种群
int parent1, parent2;
select_parents(&parent1, &parent2);
Individual child1, child2;
crossover(parent1, parent2, &child1, &child2);
mutate(&child1);
mutate(&child2);
child1.fitness = calculate_fitness(child1.x);
child2.fitness = calculate_fitness(child2.x);
new_population[i] = child1;
new_population[i + 1] = child2;
}
for (int i = 0; i < POPULATION_SIZE; i++) { // 更新种群
population[i] = new_population[i];
}
}
int main()
{
srand(time(NULL));
initialize_population();
evaluate_population();
for (int i = 0; i < GENERATION_LIMIT; i++) {
evolve();
evaluate_population();
}
return 0;
}
在此示例代码中,我们定义了一个 Individual 结构体来表示染色体,其中 x 表示染色体表示的解,fitness 表示染色体的适应度。我们使用随机数生成器 rand() 来初始化种群和进行随机操作。在 evaluate_population() 函数中,我们计算每个染色体的适应度,并记录最佳解和最佳适应度。在 select_parents() 函数中,我们使用轮盘赌选择父母。在 crossover() 函数中,我们使用单点交叉操作。在 mutate() 函数中,我们使用高斯变异操作。在 evolve() 函数中,我们使用精英策略保留前 ELITISM 个最优染色体,并产生下一代种群。最后,在 main() 函数中,我们进行多次迭代,并输出结果。
需要注意的是,这只是一个简单的示例代码,实际应用中还需要根据具体问题进行适当修改和调整。
原文地址: https://www.cveoy.top/t/topic/n2bZ 著作权归作者所有。请勿转载和采集!