#ifndef POINT_H#define POINT_Hclass Point {public: Point(double x = 0, double y = 0, double z = 0); double getX() const; double getY() const; double getZ() const;private: double x, y, z;};#endif
时间: 2023-11-20 14:07:17 浏览: 76
这是一个头文件 point.h,其中定义了一个名为 Point 的类,它有三个私有成员变量 x、y、z,分别表示三维空间中的坐标。类中有一个公有构造函数,可以传递三个参数,分别表示 x、y、z 坐标的值。另外,类中还有三个公有成员函数,分别为 getX()、getY()、getZ(),用来获取 x、y、z 坐标的值。
相关问题
改写教材例4-2中的Point类。在Point.h中定义类的属性及成员函数声明; 在Point.cpp中实现类的成员函数;在Point_Test.cpp中测试这个类。注意多文件结构的编译、编辑方法、头文件的包含关系,观察相应的成员变量取值的变化情况。
首先,在`Point.h`文件中,我们定义了一个名为`Point`的类,它包含了两个私有成员变量x和y,表示点在二维坐标系中的位置,并声明了获取和设置这些坐标的方法,以及用于计算距离的纯虚函数(因为我们需要派生类去实现具体的距离计算)。此外,还提供了一个默认构造函数和一个接受两个整数作为参数的构造函数。
```cpp
// Point.h
#ifndef _POINT_H_
#define _POINT_H_
#include <iostream>
class Point {
public:
// 构造函数
Point() : x(0), y(0) {} // 默认构造函数
Point(int x, int y) : x(x), y(y) {} // 由坐标创建点
// 成员函数声明
int getX() const; // 获取x坐标
void setX(int newX); // 设置x坐标
int getY() const; // 获取y坐标
void setY(int newY); // 设置y坐标
virtual double distanceTo(const Point& other) const = 0; // 距离计算方法(纯虚)
private:
int x;
int y;
};
#endif // _POINT_H_
```
然后,在`Point.cpp`文件中,我们实现上述声明的方法:
```cpp
// Point.cpp
#include "Point.h"
double Point::distanceTo(const Point& other) const {
return std::sqrt(std::pow(x - other.x, 2) + std::pow(y - other.y, 2));
}
int Point::getX() const { return x; }
void Point::setX(int newX) { x = newX; }
int Point::getY() const { return y; }
void Point::setY(int newY) { y = newY; }
```
接下来,在`Point_Test.cpp`文件中,我们将创建几个`Point`对象并测试它们的属性和方法:
```cpp
// Point_Test.cpp
#include "Point.h"
int main() {
Point p1; // 使用默认构造函数创建一个点
p1.setX(5);
p1.setY(10);
Point p2(15, 20); // 使用坐标创建另一个点
std::cout << "p1 coordinates: (" << p1.getX() << ", " << p1.getY() << ")\n";
std::cout << "Distance between p1 and p2: " << p1.distanceTo(p2) << "\n";
return 0;
}
```
在编译过程中,需要先分别编译`Point.cpp`和`Point_Test.cpp`(假设源代码在同一目录下),然后链接生成的`obj`文件(例如通过g++或cl编译器)。为了确保头文件之间的依赖性,记得在`Point_Test.cpp`中包含`Point.h`。
运行`Point_Test`程序,会看到不同`Point`对象的坐标以及它们之间的距离。这展示了多文件编程中如何维护类的封装性和复用性。
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文件
下面是遗传算法的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;
}
```
阅读全文