当前位置:首页 > C > 正文

C语言遗传算法实现(从零开始掌握智能优化算法)

在人工智能和优化领域,C语言遗传算法是一种非常经典且实用的智能优化方法。本教程将手把手教你如何用C语言从零开始实现一个简单的遗传算法,即使你是编程小白,也能轻松上手!

什么是遗传算法?

遗传算法(Genetic Algorithm, GA)是模拟自然界生物进化过程的一种搜索启发式算法。它通过“选择、交叉、变异”三大操作,不断迭代优化种群中的个体,最终逼近最优解。遗传算法广泛应用于函数优化、路径规划、机器学习等领域。

C语言遗传算法实现(从零开始掌握智能优化算法) C语言遗传算法 遗传算法入门 C语言实现遗传算法 智能优化算法 第1张

为什么用C语言实现遗传算法?

C语言具有高效、贴近硬件、执行速度快等优点,非常适合实现对性能要求较高的算法。同时,通过C语言实现遗传算法,你可以更深入理解算法底层逻辑,为后续学习其他智能优化算法打下坚实基础。

项目目标:求解最大值问题

我们以一个简单的目标函数为例:在区间 [0, 31] 内,找到使函数 f(x) = x² 取得最大值的整数 x。由于 31² = 961 是最大值,我们的算法应能收敛到 x=31。

我们将用5位二进制数表示 x(因为 2⁵ = 32,足够表示 0~31)。

完整C语言代码实现

以下是完整的 C语言遗传算法 实现代码,包含详细注释:

#include <stdio.h>#include <stdlib.h>#include <time.h>#define POP_SIZE 20      // 种群大小#define CHROM_LEN 5      // 染色体长度(5位二进制)#define MAX_GEN 100      // 最大进化代数#define CROSS_RATE 0.8   // 交叉概率#define MUTATE_RATE 0.05 // 变异概率typedef struct {    int chromosome[CHROM_LEN];    int value;     // 十进制值    int fitness;   // 适应度(x²)} Individual;// 将二进制染色体转为十进制int binary_to_decimal(int chrom[]) {    int val = 0;    for (int i = 0; i < CHROM_LEN; i++) {        val = val * 2 + chrom[i];    }    return val;}// 计算适应度(目标函数 f(x) = x²)int calculate_fitness(int x) {    return x * x;}// 初始化种群void init_population(Individual pop[]) {    for (int i = 0; i < POP_SIZE; i++) {        for (int j = 0; j < CHROM_LEN; j++) {            pop[i].chromosome[j] = rand() % 2;        }        pop[i].value = binary_to_decimal(pop[i].chromosome);        pop[i].fitness = calculate_fitness(pop[i].value);    }}// 轮盘赌选择Individual select(Individual pop[]) {    int total_fitness = 0;    for (int i = 0; i < POP_SIZE; i++) {        total_fitness += pop[i].fitness;    }        int r = rand() % total_fitness;    int sum = 0;    for (int i = 0; i < POP_SIZE; i++) {        sum += pop[i].fitness;        if (sum >= r) {            return pop[i];        }    }    return pop[POP_SIZE - 1];}// 单点交叉void crossover(Individual *parent1, Individual *parent2) {    if ((double)rand() / RAND_MAX < CROSS_RATE) {        int point = 1 + rand() % (CHROM_LEN - 1); // 交叉点(1~4)        for (int i = point; i < CHROM_LEN; i++) {            int temp = parent1->chromosome[i];            parent1->chromosome[i] = parent2->chromosome[i];            parent2->chromosome[i] = temp;        }        // 更新十进制值和适应度        parent1->value = binary_to_decimal(parent1->chromosome);        parent1->fitness = calculate_fitness(parent1->value);        parent2->value = binary_to_decimal(parent2->chromosome);        parent2->fitness = calculate_fitness(parent2->value);    }}// 变异void mutate(Individual *ind) {    for (int i = 0; i < CHROM_LEN; i++) {        if ((double)rand() / RAND_MAX < MUTATE_RATE) {            ind->chromosome[i] = 1 - ind->chromosome[i]; // 0变1,1变0        }    }    ind->value = binary_to_decimal(ind->chromosome);    ind->fitness = calculate_fitness(ind->value);}// 找到种群中最优个体Individual get_best(Individual pop[]) {    Individual best = pop[0];    for (int i = 1; i < POP_SIZE; i++) {        if (pop[i].fitness > best.fitness) {            best = pop[i];        }    }    return best;}int main() {    srand(time(NULL));    Individual population[POP_SIZE];    init_population(population);        printf("遗传算法求解 f(x) = x^2 在 [0,31] 的最大值\n");    printf("----------------------------------------\n");        for (int gen = 0; gen < MAX_GEN; gen++) {        Individual new_pop[POP_SIZE];                // 生成新一代        for (int i = 0; i < POP_SIZE; i += 2) {            Individual parent1 = select(population);            Individual parent2 = select(population);            crossover(&parent1, &parent2);            mutate(&parent1);            mutate(&parent2);            new_pop[i] = parent1;            if (i + 1 < POP_SIZE) {                new_pop[i + 1] = parent2;            }        }                // 更新种群        for (int i = 0; i < POP_SIZE; i++) {            population[i] = new_pop[i];        }                // 输出每10代的最佳结果        if (gen % 10 == 0 || gen == MAX_GEN - 1) {            Individual best = get_best(population);            printf("第%3d代: 最佳x=%2d, f(x)=%d\n", gen, best.value, best.fitness);        }    }        Individual final_best = get_best(population);    printf("\n最终结果: x = %d, f(x) = %d\n", final_best.value, final_best.fitness);        return 0;}

代码说明

  • 种群初始化:随机生成20个5位二进制个体。
  • 适应度计算:f(x) = x²,值越大越优。
  • 选择操作:采用轮盘赌,适应度高的个体被选中概率更大。
  • 交叉操作:以80%概率进行单点交叉。
  • 变异操作:每位以5%概率翻转(0↔1)。
  • 迭代进化:重复100代,观察是否收敛到x=31。

运行结果示例

遗传算法求解 f(x) = x^2 在 [0,31] 的最大值----------------------------------------第  0代: 最佳x=27, f(x)=729第 10代: 最佳x=30, f(x)=900第 20代: 最佳x=31, f(x)=961第 30代: 最佳x=31, f(x)=961...第 99代: 最佳x=31, f(x)=961最终结果: x = 31, f(x) = 961

总结

通过本教程,你已经掌握了如何用C语言实现一个基础的遗传算法。这不仅帮助你理解了遗传算法入门的核心思想,也为学习更复杂的智能优化算法奠定了基础。你可以尝试修改目标函数、调整参数(如种群大小、交叉率等),观察算法表现的变化。

记住,遗传算法是一种通用框架,适用于各种优化问题。只要你能定义“个体编码”和“适应度函数”,就能用它来寻找近似最优解!

动手实践是掌握算法的关键——现在就编译运行上面的代码,开启你的智能优化之旅吧!