使用c++和遗传算法解决tsp问题的代码
时间: 2023-07-28 14:07:17 浏览: 114
基于遗传算法的tsp问题的代码
3星 · 编辑精心推荐
以下是使用C++和遗传算法解决TSP问题的代码示例:
```c++
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 100; // 最大城市数
int n; // 城市数
int dist[MAXN][MAXN]; // 城市间距离矩阵
int popSize = 100; // 种群大小
double crossoverRate = 0.8; // 交叉率
double mutationRate = 0.2; // 变异率
int maxGen = 1000; // 最大迭代次数
int tournamentSize = 5; // 锦标赛选择的竞争个数
struct Chromosome {
vector<int> path; // 城市序列
double fitness; // 适应度
void init() { // 随机生成染色体
for (int i = 0; i < n; i++) path.push_back(i);
random_shuffle(path.begin(), path.end());
fitness = 0;
}
void calcFitness() { // 计算适应度
fitness = 1.0 / calcDistance();
}
double calcDistance() { // 计算旅行距离
double sum = 0;
for (int i = 0; i < n; i++) {
int x = path[i], y = path[(i + 1) % n];
sum += dist[x][y];
}
return sum;
}
};
struct Population {
vector<Chromosome> chromosomes; // 种群
void init() { // 初始化种群
for (int i = 0; i < popSize; i++) {
Chromosome c;
c.init();
chromosomes.push_back(c);
}
}
void calcFitness() { // 计算种群适应度
for (int i = 0; i < popSize; i++) {
chromosomes[i].calcFitness();
}
}
bool operator < (const Population& other) const { // 排序
return chromosomes[0].fitness > other.chromosomes[0].fitness;
}
Chromosome select() { // 锦标赛选择
Chromosome best;
for (int i = 0; i < tournamentSize; i++) {
int index = rand() % popSize;
if (i == 0 || chromosomes[index].fitness > best.fitness) {
best = chromosomes[index];
}
}
return best;
}
void crossover() { // 交叉
for (int i = 0; i < popSize; i++) {
if (rand() / (double)RAND_MAX < crossoverRate) {
Chromosome c1 = select(), c2 = select();
int pos1 = rand() % n, pos2 = rand() % n;
if (pos1 > pos2) swap(pos1, pos2);
vector<int> newpath1, newpath2;
for (int j = 0; j < n; j++) {
if (pos1 <= j && j <= pos2) {
newpath1.push_back(c2.path[j]);
newpath2.push_back(c1.path[j]);
} else {
newpath1.push_back(c1.path[j]);
newpath2.push_back(c2.path[j]);
}
}
chromosomes[i].path = newpath1;
chromosomes[i + 1].path = newpath2;
}
}
}
void mutation() { // 变异
for (int i = 0; i < popSize; i++) {
if (rand() / (double)RAND_MAX < mutationRate) {
int pos1 = rand() % n, pos2 = rand() % n;
swap(chromosomes[i].path[pos1], chromosomes[i].path[pos2]);
}
}
}
};
int main() {
srand(time(NULL));
cin >> n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> dist[i][j];
}
}
Population pop;
pop.init();
for (int gen = 0; gen < maxGen; gen++) {
pop.calcFitness();
sort(pop.chromosomes.begin(), pop.chromosomes.end());
printf("Gen %d: %.2lf\n", gen + 1, pop.chromosomes[0].fitness);
Population newpop;
newpop.chromosomes.push_back(pop.chromosomes[0]); // 保留最优个体
while (newpop.chromosomes.size() < popSize) {
newpop.chromosomes.push_back(pop.select());
}
pop = newpop;
pop.crossover();
pop.mutation();
}
return 0;
}
```
在这个示例代码中,使用了一个Chromosome结构体表示染色体,其中path表示城市序列,fitness表示适应度。使用Population结构体表示种群,其中chromosomes表示种群中的染色体。在初始化种群、计算适应度、选择、交叉、变异等操作中,都使用了各种常用的遗传算法技术,具体实现细节可以参考代码中的注释。
阅读全文