Генетический алгоритм пригодности не улучшается достаточно быстро - PullRequest
0 голосов
/ 07 июня 2019

У меня есть программа, которая пытается угадать фразу с помощью генетического алгоритма.Сначала максимальная приспособленность населения быстро увеличивается, но позже максимальная пригодность населения повышается крайне медленно.Что я могу сделать, чтобы улучшить это?

Я пытался внедрить мутацию в самих участников популяции, когда была достигнута максимальная приспособленность, которая застряла на определенном уровне в течение некоторого времени.Это решает проблему зависания программы, но не проблему того, что фитнес поднимается так медленно.

Полный код здесь: 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();
    }

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...