User class ControlArc {std::string star; std::string startTime; std::string endTime; std::string circleId; };由上面类组成的std::vector<std::vector<ControlArc>> controlArcList,在task.h文件的plan类中已经通过读外部json实例化,遗传算法每个染色体由4个基因,每个基因都是controlArcList 随机产生一定个数的vector<ControlArc>组成的数组,适应度函数是每条染色体上(endTime-startTime)值最小,请给出完整的c++遗传算法代码,其中要写.h文件和.cpp文件
时间: 2024-02-03 12:13:11 浏览: 73
下面是遗传算法的C++实现,包括.h文件和.cpp文件,代码中使用了遗传算法的常用基本操作,包括初始化种群、选择、交叉、变异等。其中,适应度函数为计算每个染色体上(endTime-startTime)值的最小值。
task.h:
```c++
#ifndef TASK_H
#define TASK_H
#include <vector>
#include <string>
class ControlArc {
public:
std::string star;
std::string startTime;
std::string endTime;
std::string circleId;
};
class Plan {
public:
std::vector<std::vector<ControlArc>> controlArcList;
Plan() {}
Plan(std::vector<std::vector<ControlArc>> controlArcList) {
this->controlArcList = controlArcList;
}
};
#endif // TASK_H
```
ga.h:
```c++
#ifndef GA_H
#define GA_H
#include <vector>
#include "task.h"
class GA {
public:
GA(int popSize, int maxGen, double pc, double pm, int geneSize, int arcNum, std::vector<std::vector<ControlArc>> controlArcList);
void run();
double fitness(Plan& p);
private:
int popSize; // 种群规模
int maxGen; // 最大迭代次数
double pc; // 交叉概率
double pm; // 变异概率
int geneSize; // 染色体长度
int arcNum; // vector<ControlArc> 数组中元素的个数
std::vector<std::vector<ControlArc>> controlArcList; // 控制弧列表
std::vector<Plan> pop; // 种群
Plan bestIndiv; // 最优个体
double bestFitness; // 最优适应度
Plan decode(std::vector<std::vector<ControlArc>> gene);
std::vector<std::vector<ControlArc>> encode(Plan indiv);
void initPop();
void select(std::vector<Plan>& newPop);
void crossover(Plan& p1, Plan& p2);
void mutate(Plan& indiv);
};
#endif // GA_H
```
ga.cpp:
```c++
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include "ga.h"
GA::GA(int popSize, int maxGen, double pc, double pm, int geneSize, int arcNum, std::vector<std::vector<ControlArc>> controlArcList) {
this->popSize = popSize;
this->maxGen = maxGen;
this->pc = pc;
this->pm = pm;
this->geneSize = geneSize;
this->arcNum = arcNum;
this->controlArcList = controlArcList;
this->bestFitness = 9999999.0;
}
void GA::run() {
srand((unsigned int)time(NULL)); // 随机数生成器初始化
initPop(); // 初始化种群
for (int i = 0; i < maxGen; i++) { // 迭代maxGen次
std::vector<Plan> newPop; // 新种群
select(newPop); // 选择
for (int j = 0; j < popSize / 2; j++) { // 交叉
Plan& p1 = newPop[j * 2];
Plan& p2 = newPop[j * 2 + 1];
crossover(p1, p2);
}
for (int j = 0; j < popSize; j++) { // 变异
mutate(newPop[j]);
}
pop = newPop;
for (int j = 0; j < popSize; j++) { // 更新最优个体和最优适应度
double fit = fitness(pop[j]);
if (fit < bestFitness) {
bestFitness = fit;
bestIndiv = pop[j];
}
}
std::cout << "第" << i + 1 << "代,最优适应度:" << bestFitness << std::endl;
}
}
double GA::fitness(Plan& p) {
std::vector<std::vector<ControlArc>> gene = encode(p);
double minEndTime = 9999999.0;
for (int i = 0; i < gene.size(); i++) {
std::vector<ControlArc>& arcs = gene[i];
double endTime = 0.0;
for (int j = 0; j < arcs.size(); j++) {
double t = atof(arcs[j].endTime.c_str()) - atof(arcs[j].startTime.c_str());
if (t > 0) { // 时间差小于0的不计算
endTime += t;
}
}
if (endTime < minEndTime) {
minEndTime = endTime;
}
}
return minEndTime;
}
Plan GA::decode(std::vector<std::vector<ControlArc>> gene) {
return Plan(gene);
}
std::vector<std::vector<ControlArc>> GA::encode(Plan indiv) {
return indiv.controlArcList;
}
void GA::initPop() {
for (int i = 0; i < popSize; i++) {
std::vector<std::vector<ControlArc>> gene(geneSize, std::vector<ControlArc>(arcNum));
for (int j = 0; j < geneSize; j++) {
for (int k = 0; k < arcNum; k++) {
gene[j][k] = controlArcList[rand() % controlArcList.size()][rand() % controlArcList[0].size()];
}
}
pop.push_back(decode(gene));
}
bestIndiv = pop[0];
bestFitness = fitness(bestIndiv);
}
void GA::select(std::vector<Plan>& newPop) {
double sumFitness = 0.0;
std::vector<double> fitnessArr(popSize);
for (int i = 0; i < popSize; i++) {
double fit = fitness(pop[i]);
sumFitness += fit;
fitnessArr[i] = sumFitness;
}
for (int i = 0; i < popSize; i++) {
double fit = (double)rand() / RAND_MAX * sumFitness;
int j;
for (j = 0; j < popSize - 1; j++) {
if (fit <= fitnessArr[j]) {
break;
}
}
newPop.push_back(pop[j]);
}
}
void GA::crossover(Plan& p1, Plan& p2) {
if ((double)rand() / RAND_MAX < pc) { // 满足概率要求
int point1 = rand() % geneSize;
int point2 = rand() % geneSize;
if (point1 > point2) { // 确保point1小于point2
int temp = point1;
point1 = point2;
point2 = temp;
}
std::vector<std::vector<ControlArc>> gene1 = encode(p1);
std::vector<std::vector<ControlArc>> gene2 = encode(p2);
for (int i = point1; i <= point2; i++) { // 交叉基因
std::vector<ControlArc> temp = gene1[i];
gene1[i] = gene2[i];
gene2[i] = temp;
}
p1 = decode(gene1);
p2 = decode(gene2);
}
}
void GA::mutate(Plan& indiv) {
if ((double)rand() / RAND_MAX < pm) { // 满足概率要求
std::vector<std::vector<ControlArc>> gene = encode(indiv);
int point = rand() % geneSize;
for (int i = 0; i < arcNum; i++) { // 变异基因
gene[point][i] = controlArcList[rand() % controlArcList.size()][rand() % controlArcList[0].size()];
}
indiv = decode(gene);
}
}
```
使用方法:
```c++
#include <vector>
#include <fstream>
#include "ga.h"
#include "task.h"
using namespace std;
int main()
{
int popSize = 50; // 种群规模
int maxGen = 100; // 最大迭代次数
double pc = 0.8; // 交叉概率
double pm = 0.2; // 变异概率
int geneSize = 4; // 染色体长度
int arcNum = 10; // vector<ControlArc> 数组中元素的个数
// 读取控制弧列表
ifstream fin("controlArcList.json");
nlohmann::json j;
fin >> j;
vector<vector<ControlArc>> controlArcList = j.get<vector<vector<ControlArc>>>();
GA ga(popSize, maxGen, pc, pm, geneSize, arcNum, controlArcList);
ga.run();
return 0;
}
```
阅读全文