我有一个程序试图通过使用遗传算法来猜测一个短语。最初,人口的最大适应度迅速上升,但后来人口的最大适应度分数却非常缓慢地上升。我该怎么做才能改善这一点?
只要最大适应度停留在特定分数上一段时间,我就会尝试将变异引入种群成员本身。这解决了程序卡住的问题,但解决了适应性上升得太慢的问题。
完整代码在这里: https://github.com/bharddwaj/First-Genetic-Algorithm/tree/master/Genetic%20Algorithm
健身得分只是程序尝试猜测的与实际句子共享的字符数。
Chromosome crossOver2(Chromosome parentOne,Chromosome parentTwo,int numChanges){
//generates child by switching n random elements between the two SELECTED parents resulting in two children
//then the function random returns one of the children
//IMPORTANT NOTE: I am not using pass by reference so the parameters are merely copies
std::unordered_map<int, char> genesHolder;
for (int i = 0; i < numChanges; i++) {
std::random_device rd;
std::mt19937 generator(rd());
std::uniform_int_distribution<int> distribution2(0, members[0].getChromosomeLength() - 1); // inclusive
int rand_num_3 = distribution2(generator);
char gene = parentOne.genes[rand_num_3];
genesHolder[rand_num_3] = gene;
parentOne.genes[rand_num_3] = parentTwo.genes[rand_num_3];
}
std::unordered_map<int, char>::iterator it;
for (auto it: genesHolder) {
int key = it.first; // first accesses the key while second accesses the value
char value = it.second;
parentTwo.genes[key] = value;
}
std::uniform_int_distribution<int> distribution3(0, 1);
std::random_device rd;
std::mt19937 generator(rd());
int rand_num_4 = distribution3(generator);
if (rand_num_4 == 0){
parentOne.calcFitness();
return parentOne;
}
parentTwo.calcFitness();
return parentTwo;
}
void mutation(int mutationPercent,Chromosome &child,int numChanges){
std::random_device rd;
std::mt19937 generator(rd());
std::uniform_int_distribution<int> distribution(0, 100);
int rand_var = distribution(generator);
if (rand_var <= mutationPercent) {
for (int i = 0; i < numChanges ; i++) {
std::random_device rd;
std::mt19937 generator(rd());
std::uniform_int_distribution<int> distribution2(0, members[0].getChromosomeLength() - 1);
int rand_var_2 = distribution2(generator);
std::uniform_int_distribution<int> distribution3(0, characters.size() - 1);
int rand_var_3 = distribution3(generator);
child.genes[rand_var_2] = characters[rand_var_3];
}
}
}
void generateChildren3(int numChildren,int mutationPercent, int numMutationChanges,int numCrossoverChanges){
//inefficient wheel of fortune method
//using weighted probabilities based on fitness to 'spin the wheel' for who reproduces
//going to use normalization method sooner or later
std::vector<Chromosome> wheel;
int fitness;
int maxFitness = getMaxFitness();
for (int i = 0; i < members.size(); i++) {
fitness = members[i].fitness;
int limit = (((float)(fitness))/((float)(members[i].getChromosomeLength())))*100;
for (int j = 0; j < limit; j++) {
wheel.push_back(members[i]);
}
}
for (int children = 0; children < numChildren; children++) {
std::random_device rd;
std::mt19937 generator(rd());
std::uniform_int_distribution<int> distribution(0, 100);
int rand_var = distribution(generator);
int rand_var2 = distribution(generator);
Chromosome parentOne = (wheel[rand_var]);
Chromosome parentTwo = (wheel[rand_var2]);
//Chromosome child = crossOver2(parentOne,parentTwo, numCrossoverChanges);
Chromosome child = crossOver3(parentOne,parentTwo);
mutation(mutationPercent, child, numMutationChanges);
members.push_back(child);
}
calcAllFitness();
wheel.clear();
}