找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 99|回复: 1

c++代码 遗传算法 包含轮盘赌

[复制链接]

0

主题

0

回帖

26

积分

管理员

积分
26
发表于 2024-6-29 16:48:49 | 显示全部楼层
遗传算法是一种搜索启发式算法,灵感来源于自然选择和遗传学原理,常用于优化和搜索问题。下面是一个简化的遗传算法示例,使用轮盘赌选择(roulette wheel selection)来进行个体的选择,以解决一个简单的最大化问题。我们将尝试最大化一个由二进制编码表示的目标函数。
  1. ```cpp
  2. #include <iostream>
  3. #include <vector>
  4. #include <cstdlib>
  5. #include <ctime>
  6. #include <algorithm>
  7. #include <numeric>
  8. // 个体类
  9. class Individual {
  10. public:
  11.     std::vector<int> genes; // 基因,即二进制编码
  12.     double fitness; // 适应度
  13.     Individual(int geneLength) : genes(geneLength), fitness(0.0) {
  14.         // 初始化基因
  15.         for (int& g : genes) {
  16.             g = rand() % 2;
  17.         }
  18.     }
  19.     void calculateFitness() {
  20.         // 假设目标函数是要最大化二进制编码表示的十进制数
  21.         fitness = std::accumulate(genes.begin(), genes.end(), 0.0,
  22.                                   [](double total, int bit) { return total * 2 + bit; });
  23.     }
  24. };
  25. // 轮盘赌选择
  26. Individual rouletteWheelSelection(const std::vector<Individual>& population) {
  27.     double totalFitness = std::accumulate(population.begin(), population.end(), 0.0,
  28.                                           [](double total, const Individual& ind) { return total + ind.fitness; });
  29.     double pick = static_cast<double>(rand()) / RAND_MAX * totalFitness;
  30.     double current = 0.0;
  31.     for (const auto& individual : population) {
  32.         current += individual.fitness;
  33.         if (current > pick) {
  34.             return individual;
  35.         }
  36.     }
  37.     // 默认返回最后一个个体
  38.     return population.back();
  39. }
  40. // 遗传算法主循环
  41. void geneticAlgorithm(int populationSize, int geneLength, int generations) {
  42.     srand(static_cast<unsigned int>(time(nullptr)));
  43.     std::vector<Individual> population(populationSize);
  44.     for (auto& individual : population) {
  45.         individual.genes.resize(geneLength);
  46.     }
  47.     for (int generation = 0; generation < generations; ++generation) {
  48.         for (auto& individual : population) {
  49.             individual.calculateFitness();
  50.         }
  51.         // 打印当前最优个体的适应度
  52.         std::sort(population.begin(), population.end(),
  53.                   [](const Individual& a, const Individual& b) { return a.fitness > b.fitness; });
  54.         std::cout << "Generation " << generation << ": Best Fitness = " << population.front().fitness << std::endl;
  55.         std::vector<Individual> newPopulation;
  56.         while (newPopulation.size() < populationSize) {
  57.             Individual parent1 = rouletteWheelSelection(population);
  58.             Individual parent2 = rouletteWheelSelection(population);
  59.             // 进行交叉和变异,生成新个体
  60.             Individual child = parent1; // 假设无交叉,直接复制父代
  61.             // 变异操作
  62.             for (int i = 0; i < geneLength; ++i) {
  63.                 if (static_cast<double>(rand()) / RAND_MAX < 0.05) { // 变异概率5%
  64.                     child.genes[i] = 1 - child.genes[i];
  65.                 }
  66.             }
  67.             newPopulation.push_back(child);
  68.         }
  69.         population = newPopulation;
  70.     }
  71. }
  72. int main() {
  73.     geneticAlgorithm(100, 10, 100); // 100个个体,每个个体10个基因,运行100代
  74.     return 0;
  75. }
  76. ```
复制代码

在上述代码中,我们定义了一个`Individual`类来表示个体,它包含了一组基因(`genes`)和一个适应度值(`fitness`)。遗传算法的主要循环包括计算适应度、轮盘赌选择、交叉和变异等步骤。这里为了简化,我们省略了交叉操作,只进行了变异。轮盘赌选择是基于个体适应度的大小来进行选择,适应度越高的个体被选中的概率越大。

请注意,遗传算法的效果很大程度上取决于问题的特性、种群大小、基因长度、交叉和变异策略等参数的设置。在实际应用中,可能需要对这些参数进行调整以获得最佳效果。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|膜结构网

GMT+8, 2024-12-27 22:11 , Processed in 0.168213 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表