遗传算法select函数C++
时间: 2024-01-15 10:04:23 浏览: 100
遗传算法的select函数是用来选择适应度高的个体,进入下一代的过程。常见的选择方法有轮盘赌选择、锦标赛选择、随机选择等。以下是一个简单的轮盘赌选择的示例代码:
```c++
vector<int> select(vector<double>& fitness, int n) {
vector<int> res;
double sum = accumulate(fitness.begin(), fitness.end(), 0.0);
vector<double> prob(fitness.size());
partial_sum(fitness.begin(), fitness.end(), prob.begin(), [&sum](double a, double b) { return a + b / sum; });
for (int i = 0; i < n; ++i) {
double r = (double)rand() / RAND_MAX; auto it = lower_bound(prob.begin(), prob.end(), r);
res.push_back(it - prob.begin());
}
return res;
}
```
其中,fitness是每个个体的适应度,n是需要选择的个体数。函数返回一个vector,包含n个被选择的个体的下标。
相关问题
遗传算法求函数最大值,并给出C++示例
遗传算法是一种基于生物进化原理的优化算法,可以用于求解函数最大值问题。其基本思路是通过模拟自然选择、交叉和变异等生物进化过程,从而逐步优化得到最优解。
下面是一个简单的遗传算法的C++示例,用于求解函数f(x) = x^2在区间[-10, 10]上的最大值:
```c++
#include <iostream>
#include <cmath>
#include <random>
#include <algorithm>
#include <vector>
using namespace std;
// 目标函数
double f(double x) {
return x * x;
}
// 遗传算法参数
const int POPULATION_SIZE = 100; // 种群大小
const int MAX_GENERATION = 100; // 最大迭代次数
const double CROSSOVER_RATE = 0.8; // 交叉概率
const double MUTATION_RATE = 0.01; // 变异概率
// 个体结构体
struct Individual {
double x; // 自变量
double fitness; // 适应度
// 构造函数
Individual(double x) {
this->x = x;
fitness = f(x);
}
// 重载小于运算符
bool operator<(const Individual& other) const {
return fitness > other.fitness;
}
};
// 随机数生成器
random_device rd;
mt19937 gen(rd());
uniform_real_distribution<> dis(-10, 10);
// 初始化种群
vector<Individual> init_population() {
vector<Individual> population;
for (int i = 0; i < POPULATION_SIZE; i++) {
double x = dis(gen);
population.emplace_back(x);
}
return population;
}
// 计算适应度
void evaluate(vector<Individual>& population) {
for (auto& ind : population) {
ind.fitness = f(ind.x);
}
}
// 选择操作
Individual select(const vector<Individual>& population) {
uniform_int_distribution<> dis(0, POPULATION_SIZE - 1);
int index1 = dis(gen);
int index2 = dis(gen);
return population[index1].fitness > population[index2].fitness ?
population[index1] : population[index2];
}
// 交叉操作
Individual crossover(const Individual& parent1, const Individual& parent2) {
uniform_real_distribution<> dis(0, 1);
if (dis(gen) > CROSSOVER_RATE) {
return parent1;
}
double x = (parent1.x + parent2.x) / 2;
return Individual(x);
}
// 变异操作
void mutate(Individual& ind) {
uniform_real_distribution<> dis(-1, 1);
if (dis(gen) > MUTATION_RATE) {
return;
}
ind.x += dis(gen);
}
// 遗传算法主函数
double genetic_algorithm() {
vector<Individual> population = init_population();
evaluate(population);
sort(population.begin(), population.end());
for (int i = 0; i < MAX_GENERATION; i++) {
vector<Individual> new_population;
while (new_population.size() < POPULATION_SIZE) {
Individual parent1 = select(population);
Individual parent2 = select(population);
Individual child = crossover(parent1, parent2);
mutate(child);
new_population.emplace_back(child);
}
evaluate(new_population);
sort(new_population.begin(), new_population.end());
population = new_population;
}
return population.front().x;
}
int main() {
double x_max = genetic_algorithm();
cout << "x_max = " << x_max << ", f(x_max) = " << f(x_max) << endl;
return 0;
}
```
该示例中,我们首先定义了目标函数f(x),然后定义了遗传算法的一些参数和个体结构体。在初始化种群时,我们使用了C++11中的emplace_back函数,可以避免不必要的拷贝操作,提高程序效率。在遗传算法的主函数中,我们首先进行了种群初始化和适应度计算,然后进行了迭代过程。在每一次迭代中,我们使用了轮盘赌选择和简单的算术交叉和随机变异操作。最终,我们输出了求得的最大值x_max及其对应的函数值f(x_max)。
需要注意的是,遗传算法只能求解单峰函数的最大值,对于多峰函数或者具有约束条件的问题,可能需要使用其他的优化算法。
遗传算法c++
遗传算法是一种基于自然选择和遗传学的优化算法,可以用于解决很多实际问题,如函数优化、机器学习、图像处理等。
在C++中,实现遗传算法的基本步骤如下:
1. 定义问题的目标函数和适应度函数;
2. 将问题转换为一个个体的基因编码;
3. 初始化种群,即生成随机的初始个体;
4. 计算每个个体的适应度值;
5. 选择操作,根据适应度值选择优秀个体并产生新的个体;
6. 交叉操作,将选中的个体进行交叉产生新的个体;
7. 变异操作,对新个体进行变异,增加种群的多样性;
8. 重复执行步骤4-7,直到满足停止条件,如达到最大迭代次数或目标函数已经收敛。
下面是一个简单的遗传算法的C++程序示例:
```
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
using namespace std;
const int POPULATION_SIZE = 100; // 种群大小
const int GENE_SIZE = 10; // 基因长度
const int MAX_ITERATION = 100; // 最大迭代次数
// 个体类
class Individual {
public:
vector<int> genes;
double fitness;
Individual() {
genes.resize(GENE_SIZE);
for (int i = 0; i < GENE_SIZE; i++) {
genes[i] = rand() % 2; // 随机生成0或1
}
fitness = 0;
}
void evaluate() {
// 计算适应度值,以目标函数的值为适应度值
double x = 0;
for (int i = 0; i < GENE_SIZE; i++) {
x += genes[i] * pow(2, GENE_SIZE - i - 1);
}
fitness = x * x;
}
bool operator < (const Individual& other) const {
return fitness < other.fitness;
}
};
// 遗传算法类
class GeneticAlgorithm {
public:
vector<Individual> population;
GeneticAlgorithm() {
population.resize(POPULATION_SIZE);
for (int i = 0; i < POPULATION_SIZE; i++) {
population[i] = Individual();
}
}
void evaluate() {
// 计算种群中每个个体的适应度值
for (int i = 0; i < POPULATION_SIZE; i++) {
population[i].evaluate();
}
sort(population.begin(), population.end()); // 按适应度值从小到大排序
}
void select() {
// 选择操作,采用轮盘赌选择方法
vector<Individual> newPopulation;
double totalFitness = 0;
for (int i = 0; i < POPULATION_SIZE; i++) {
totalFitness += population[i].fitness;
}
for (int i = 0; i < POPULATION_SIZE; i++) {
double r = ((double)rand() / RAND_MAX) * totalFitness;
double sum = 0;
for (int j = 0; j < POPULATION_SIZE; j++) {
sum += population[j].fitness;
if (sum >= r) {
newPopulation.push_back(population[j]);
break;
}
}
}
population = newPopulation;
}
void crossover() {
// 交叉操作,采用单点交叉方法
for (int i = 0; i < POPULATION_SIZE; i += 2) {
int pos = rand() % GENE_SIZE;
for (int j = pos; j < GENE_SIZE; j++) {
swap(population[i].genes[j], population[i + 1].genes[j]);
}
}
}
void mutate() {
// 变异操作,采用单点变异方法
for (int i = 0; i < POPULATION_SIZE; i++) {
for (int j = 0; j < GENE_SIZE; j++) {
double r = (double)rand() / RAND_MAX;
if (r < 0.01) { // 变异概率为1%
population[i].genes[j] = 1 - population[i].genes[j];
}
}
}
}
void run() {
srand((unsigned)time(NULL));
for (int i = 0; i < MAX_ITERATION; i++) {
evaluate();
cout << "Iteration " << i + 1 << ": " << population[0].fitness << endl;
if (population[0].fitness == 0) break; // 目标函数已经收敛,停止迭代
select();
crossover();
mutate();
}
}
};
int main() {
GeneticAlgorithm ga;
ga.run();
return 0;
}
```
该程序实现了一个简单的遗传算法,用于求解一个二进制数的平方的最小值。其中,个体类表示一个二进制数,遗传算法类中实现了选择、交叉和变异操作。程序运行后,输出每次迭代的最优适应度值。
阅读全文