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

C++遗传算法实战指南(从零开始实现智能优化算法)

在人工智能和优化领域,C++遗传算法是一种模拟自然选择和生物进化过程的启发式搜索算法。它被广泛应用于解决复杂的优化问题,如函数优化、路径规划、机器学习参数调优等。本教程将带你从零开始,用C++语言一步步实现一个完整的遗传算法,即使你是编程小白也能轻松上手!

什么是遗传算法?

遗传算法(Genetic Algorithm, GA)受达尔文“物竞天择,适者生存”思想启发,通过模拟生物进化过程来寻找最优解。其核心操作包括:选择(Selection)交叉(Crossover)变异(Mutation)

C++遗传算法实战指南(从零开始实现智能优化算法) C++遗传算法 遗传算法实现 C++优化算法 智能算法编程 第1张

项目目标

我们将用C++实现一个简单的遗传算法,目标是找到函数 f(x) = x² 在区间 [0, 31] 内的最大值。由于x为整数,最大值出现在x=31时,f(x)=961。我们将用5位二进制串表示x(因为2⁵=32,足够表示0~31)。

完整C++代码实现

下面是一个完整的、可运行的C++遗传算法实现:

#include <iostream>#include <vector>#include <random>#include <algorithm>#include <cmath>using namespace std;const int POPULATION_SIZE = 20;   // 种群大小const int CHROMOSOME_LENGTH = 5;  // 染色体长度(5位二进制)const double MUTATION_RATE = 0.01; // 变异率const int MAX_GENERATIONS = 100;  // 最大迭代代数// 将二进制染色体转换为十进制整数int binaryToDecimal(const vector<int>& chromosome) {    int value = 0;    for (int i = 0; i < CHROMOSOME_LENGTH; ++i) {        value += chromosome[i] * pow(2, CHROMOSOME_LENGTH - 1 - i);    }    return value;}// 计算个体适应度(目标函数 f(x) = x^2)int calculateFitness(const vector<int>& chromosome) {    int x = binaryToDecimal(chromosome);    return x * x;}// 初始化随机种群vector<vector<int>> initializePopulation() {    vector<vector<int>> population(POPULATION_SIZE, vector<int>(CHROMOSOME_LENGTH));    random_device rd;    mt19937 gen(rd());    uniform_int_distribution<> dis(0, 1);    for (auto& individual : population) {        for (int& gene : individual) {            gene = dis(gen);        }    }    return population;}// 轮盘赌选择vector<int> rouletteWheelSelection(const vector<vector<int>>& population,                                   const vector<int>& fitnesses) {    int totalFitness = 0;    for (int f : fitnesses) totalFitness += f;    random_device rd;    mt19937 gen(rd());    uniform_int_distribution<> dis(0, totalFitness - 1);    int pick = dis(gen);    int current = 0;    for (size_t i = 0; i < population.size(); ++i) {        current += fitnesses[i];        if (pick < current) {            return population[i];        }    }    return population.back();}// 单点交叉pair<vector<int>, vector<int>> crossover(const vector<int>& parent1,                                          const vector<int>& parent2) {    random_device rd;    mt19937 gen(rd());    uniform_int_distribution<> dis(1, CHROMOSOME_LENGTH - 1);    int crossoverPoint = dis(gen);    vector<int> child1(parent1.begin(), parent1.begin() + crossoverPoint);    vector<int> child2(parent2.begin(), parent2.begin() + crossoverPoint);    child1.insert(child1.end(), parent2.begin() + crossoverPoint, parent2.end());    child2.insert(child2.end(), parent1.begin() + crossoverPoint, parent1.end());    return make_pair(child1, child2);}// 变异void mutate(vector<int>& chromosome) {    random_device rd;    mt19937 gen(rd());    uniform_real_distribution<> dis(0.0, 1.0);    for (int& gene : chromosome) {        if (dis(gen) < MUTATION_RATE) {            gene = 1 - gene; // 0变1,1变0        }    }}int main() {    // 初始化种群    auto population = initializePopulation();    for (int generation = 0; generation < MAX_GENERATIONS; ++generation) {        // 计算每个个体的适应度        vector<int> fitnesses;        for (const auto& individual : population) {            fitnesses.push_back(calculateFitness(individual));        }        // 找到当前最佳个体        int bestIndex = max_element(fitnesses.begin(), fitnesses.end()) - fitnesses.begin();        int bestValue = binaryToDecimal(population[bestIndex]);        int bestFitness = fitnesses[bestIndex];        cout << "第 " << generation + 1 << " 代: 最佳x = " << bestValue              << ", f(x) = " << bestFitness << endl;        // 如果找到最优解,提前结束        if (bestFitness == 961) {            cout << "\n🎉 找到最优解!x = 31, f(x) = 961" << endl;            break;        }        // 创建新一代种群        vector<vector<int>> newPopulation;        while (newPopulation.size() < POPULATION_SIZE) {            auto parent1 = rouletteWheelSelection(population, fitnesses);            auto parent2 = rouletteWheelSelection(population, fitnesses);            auto children = crossover(parent1, parent2);            mutate(children.first);            mutate(children.second);            newPopulation.push_back(children.first);            if (newPopulation.size() < POPULATION_SIZE) {                newPopulation.push_back(children.second);            }        }        population = move(newPopulation);    }    return 0;}

代码详解

  • 种群初始化:使用随机数生成器创建初始个体,每个个体是一个5位二进制向量。
  • 适应度计算:将二进制转换为十进制后,计算 作为适应度值。
  • 选择操作:采用轮盘赌选择,适应度越高的个体被选中的概率越大。
  • 交叉操作:随机选择一个交叉点,交换两个父代的部分基因生成子代。
  • 变异操作:以低概率(1%)随机翻转某个基因位,增加种群多样性。

如何编译和运行

将上述代码保存为 genetic_algorithm.cpp,然后在终端执行:

g++ -std=c++11 genetic_algorithm.cpp -o ga./ga

你将看到每一代的最佳解逐步逼近31,最终找到全局最优解。

总结

通过本教程,你已经掌握了如何用C++实现一个基础的遗传算法实现。这种C++优化算法具有通用性强、鲁棒性好等优点,适用于各种复杂优化场景。下一步,你可以尝试修改目标函数、调整参数(如种群大小、变异率),或将其应用于更复杂的智能算法编程任务中,如TSP旅行商问题、神经网络权重优化等。

提示:遗传算法虽强大,但并非万能。对于某些问题,可能需要结合其他优化技术才能获得最佳效果。