void MimicGa::_updateScores() { GeneticAlgorithm::_updateScores(); // sort in descending order sort(_population.begin(), _population.end(), CompareGenomes()); WeightMap oldWeights = _weights; _weights.clear(); // @todo test this // // if we're stagnating, start bringing the weights back together. This should help broaden // // the search a bit. // if (_lastBest == _population[0]->getScore()) // { // _stagnation++; // for (WeightMap::iterator it = oldWeights.begin(); it != oldWeights.end(); ++it) // { // it->second = pow(it->second, 1.0 / (double)_stagnation); // } // _normalize(oldWeights); // } boost::shared_ptr<CalculatorGenome> cg = boost::dynamic_pointer_cast<CalculatorGenome>(_population[0]); const CalculatorGenome::AvailableNodeMap& anm = cg->getAvailableNodes(); for (CalculatorGenome::AvailableNodeMap::const_iterator it = anm.begin(); it != anm.end(); ++it) { _weights[it->first] = 1e-5; } for (unsigned int i = 0; i < _population.size() * _thetaPercentile; i++) { cg = boost::dynamic_pointer_cast<CalculatorGenome>(_population[i]); assert(cg); _populateWeights(cg->getRoot()); } // normalize the weights so they sum to 1 _normalize(_weights); if (oldWeights.size() > 0) { for (WeightMap::iterator it = _weights.begin(); it != _weights.end(); ++it) { it->second = it->second * _learningRate + oldWeights[it->first] * (1 - _learningRate); //cout << it->first << "\t" << it->second << endl; } } // for (WeightMap::iterator it = _weights.begin(); it != _weights.end(); ++it) // { // cout << it->first << "\t" << it->second << endl; // } }
void GeneticAlgorithm::step() { // the first step is just initialization if (_initialized == false) { initialize(); sort(_population.begin(), _population.end(), CompareGenomes()); return; } if (_best->getScore() == numeric_limits<double>::infinity()) { return; } // sort in descending order sort(_population.begin(), _population.end(), CompareGenomes()); vector< shared_ptr<Genome> > nextGen; nextGen.reserve(_populationSize); for (int i = 0; i < _keepBest && i < (int)_population.size(); i++) { nextGen.push_back(_population[i]->clone()); } for (int i = 0; i < _keepBest && i < (int)_population.size(); i++) { shared_ptr<Genome> g = _population[i]->clone(); g->mutate(_mutationSeverity); nextGen.push_back(g); } for (int i = 0; i < _freshMeat; i++) { shared_ptr<Genome> g = _seed->clone(); _initializeGenome(g); if (_used.find(g->toString()) == _used.end()) { nextGen.push_back(g); _used.insert(g->toString()); } } while ((int)nextGen.size() < _populationSize) { // if (nextGen.size() % 500 == 0 && nextGen.size() > 0) // { // cout << nextGen.size() << "/" << _populationSize << "\r"; // cout.flush(); // } // choose the act of 'god' double act = Tgs::Random::instance()->generateUniform(); //double mutate = Tgs::Random::instance()->generateUniform(); // if they get a free pass, randomly select a genome and pass it on to the next gen if (act < _mutationProb) { int index = _selectMateRoulette(); shared_ptr<Genome> genome = _population[index]->clone(); _mutate(genome); // // make sure at least half of the new generation is unique // if ((int)nextGen.size() < _populationSize / 4) // { // if (_used.find(genome->toString()) == _used.end()) // { // nextGen.push_back(genome); // } // } // else { nextGen.push_back(genome); } } // otherwise we're mating something else { int fatherIndex = _selectMateTournament(); int motherIndex = _selectMateTournament(); if (fatherIndex != motherIndex) { shared_ptr<Genome> father = _population[fatherIndex]; shared_ptr<Genome> mother = _population[motherIndex]; shared_ptr<Genome> brother, sister; father->crossoverSexually(*father, *mother, brother, sister); // if (mutate < _mutationProb) // { // brother->mutate(_mutationSeverity); // sister->mutate(_mutationSeverity); // } // // make sure at least one fourth of the new generation is unique // if ((int)nextGen.size() < _populationSize / 4) // { // if (_used.find(brother->toString()) == _used.end()) // { // nextGen.push_back(brother); // _used.insert(brother->toString()); // } // if ((int)nextGen.size() < _populationSize) // { // if (_used.find(sister->toString()) == _used.end()) // { // nextGen.push_back(sister); // _used.insert(sister->toString()); // } // } // } // else { nextGen.push_back(brother); _used.insert(brother->toString()); nextGen.push_back(sister); _used.insert(sister->toString()); } } } } //cout << " \r"; _population = nextGen; _updateScores(); // // sort in descending order // sort(_population.begin(), _population.end(), CompareGenomes()); // nextGen.clear(); // string lastStr = _population[0]->toString(); // nextGen.push_back(_population[0]); // for (unsigned int i = 1; i < _population.size(); i++) // { // if (_population[i]->toString() != lastStr) // { // nextGen.push_back(_population[i]); // lastStr = _population[i]->toString(); // } // } // _population = nextGen; }