Esempio n. 1
0
  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;
//     }
  }
Esempio n. 2
0
  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;
  }