|
发表于 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[i] = 1 - child.genes[i];
- }
- }
- newPopulation.push_back(child);
- }
- population = newPopulation;
- }
- }
- int main() {
- geneticAlgorithm(100, 10, 100); // 100个个体,每个个体10个基因,运行100代
- return 0;
- }
- ```
复制代码
在上述代码中,我们定义了一个`Individual`类来表示个体,它包含了一组基因(`genes`)和一个适应度值(`fitness`)。遗传算法的主要循环包括计算适应度、轮盘赌选择、交叉和变异等步骤。这里为了简化,我们省略了交叉操作,只进行了变异。轮盘赌选择是基于个体适应度的大小来进行选择,适应度越高的个体被选中的概率越大。
请注意,遗传算法的效果很大程度上取决于问题的特性、种群大小、基因长度、交叉和变异策略等参数的设置。在实际应用中,可能需要对这些参数进行调整以获得最佳效果。 |
|