在普通的遗传算法的基础上,每个个体引入显隐性染色体。
算法流程:
- 初始化种群
- 根据显性染色体进行选择
- 个体之间交叉时:显性和显性交叉。隐性和隐性交叉
- 个体中显性以较小的变异概率变异,隐性以较大的变异概率变异
以下代码使用双倍体的遗传算法解决TSP问题,城市数量34.
```cpp
//双色体遗传算法
#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
#include<time.h>
using namespace std;
typedef vector<int> Vi;
//typedef vector<Vi> Vii;
struct Obj{
pair<double, Vi*> xian; // 显性染色体
pair<double, Vi*> yin; // 隐形染色体
friend operator <(Obj &o1, Obj &o2){
return o1.xian.first > o2.xian.first;
}
};
Vi x; //城市的横坐标
Vi y; //城市的纵坐标
/*
1. 采用适应度比例分配个体的选择概率,
2. 采用轮盘赌选择个体
3. 采用pxm交叉
4. 采用两点互换的变异方式
*/
bool cmp(Obj * x, Obj *y){ //sort的比较函数
return x->xian > y->xian;
}
int next_int(){
return rand()*(RAND_MAX+1)+rand();
}
double next_double(){
return (double(rand()*(RAND_MAX+1)+rand()))/((RAND_MAX+1)*RAND_MAX+RAND_MAX);
}
void pmx(Vi& a,Vi&b, int chroLength);
double fitness( Vi& v,int chroLength);
void change0(vector<int>& K,int N);
void change1(vector<int>& K, int N);
void mutate(Vi& route,int mutate_type,int popSize);
class population{
public:
int popSize, chroLength; // 种群大小、染色体长度
double pc, pmL, pmH; //交叉概率、较小的变异概率、较大的变异概率
vector<Obj *> pop; // 种群
pair<double, Vi *> bestOne;
population(int popsize, int chrolength, double pc, double pml, double pmh){
popSize = popsize;chroLength = chrolength; this->pc = pc; pmL = pml; pmH = pmh; //相应赋值
//初始化种群
for(int i = 0; i < popsize; ++i){
Obj * o = new Obj{};
Vi *chro1 = new Vi(chroLength);
double fit1;
Vi *chro2 = new Vi(chroLength);
double fit2;
for(int j = 0; j < chrolength; ++j){ //产生顺序
(*chro1)[j] = j;
(*chro2)[j] = j;
}
random_shuffle(chro1->begin(), chro1->end()); //打乱元素
random_shuffle(chro2->begin(), chro2->end()); //打乱元素
fit1 = fitness(*chro1, chrolength);
fit2 = fitness(*chro2, chrolength);
if(fit1 >= fit