admin 发表于 2024-6-29 16:48:49

遗传算法是一种搜索启发式算法,灵感来源于自然选择和遗传学原理,常用于优化和搜索问题。下面是一个简化的遗传算法示例,使用轮盘赌选择(roulette wheel selection)来进行个体的选择,以解决一个简单的最大化问题。我们将尝试最大化一个由二进制编码表示的目标函数。

```cpp
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <numeric>

// 个体类
class Individual {
public:
    std::vector<int> genes; // 基因,即二进制编码
    double fitness; // 适应度

    Individual(int geneLength) : genes(geneLength), fitness(0.0) {
      // 初始化基因
      for (int& g : genes) {
            g = rand() % 2;
      }
    }

    void calculateFitness() {
      // 假设目标函数是要最大化二进制编码表示的十进制数
      fitness = std::accumulate(genes.begin(), genes.end(), 0.0,
                                  [](double total, int bit) { return total * 2 + bit; });
    }
};

// 轮盘赌选择
Individual rouletteWheelSelection(const std::vector<Individual>& population) {
    double totalFitness = std::accumulate(population.begin(), population.end(), 0.0,
                                          [](double total, const Individual& ind) { return total + ind.fitness; });

    double pick = static_cast<double>(rand()) / RAND_MAX * totalFitness;
    double current = 0.0;

    for (const auto& individual : population) {
      current += individual.fitness;
      if (current > pick) {
            return individual;
      }
    }

    // 默认返回最后一个个体
    return population.back();
}

// 遗传算法主循环
void geneticAlgorithm(int populationSize, int geneLength, int generations) {
    srand(static_cast<unsigned int>(time(nullptr)));

    std::vector<Individual> population(populationSize);
    for (auto& individual : population) {
      individual.genes.resize(geneLength);
    }

    for (int generation = 0; generation < generations; ++generation) {
      for (auto& individual : population) {
            individual.calculateFitness();
      }

      // 打印当前最优个体的适应度
      std::sort(population.begin(), population.end(),
                  [](const Individual& a, const Individual& b) { return a.fitness > b.fitness; });
      std::cout << "Generation " << generation << ": Best Fitness = " << population.front().fitness << std::endl;

      std::vector<Individual> newPopulation;
      while (newPopulation.size() < populationSize) {
            Individual parent1 = rouletteWheelSelection(population);
            Individual parent2 = rouletteWheelSelection(population);
            // 进行交叉和变异,生成新个体
            Individual child = parent1; // 假设无交叉,直接复制父代
            // 变异操作
            for (int i = 0; i < geneLength; ++i) {
                if (static_cast<double>(rand()) / RAND_MAX < 0.05) { // 变异概率5%
                  child.genes = 1 - child.genes;
                }
            }
            newPopulation.push_back(child);
      }
      population = newPopulation;
    }
}

int main() {
    geneticAlgorithm(100, 10, 100); // 100个个体,每个个体10个基因,运行100代
    return 0;
}
```

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

请注意,遗传算法的效果很大程度上取决于问题的特性、种群大小、基因长度、交叉和变异策略等参数的设置。在实际应用中,可能需要对这些参数进行调整以获得最佳效果。
页: [1]
查看完整版本: c++代码 遗传算法 包含轮盘赌