Пример #1
0
void crossover_function(population& p)
{
  population new_population;
  std::vector<int> cross_set;
  std::vector<int>::iterator it;
  float rd;
  
  // choose which specimen will crossover
  for(int i=0; i<population_size; i++)
  {
    rd = (randid()*1.0f) / (RAND_MAX*1.0f*population_size);
    if(rd > p[i].adapt)
      cross_set.push_back(i);
  }
  
  // we want even number of parents
  if(cross_set.size() & 1)
    cross_set.pop_back();

  // more randomness
  random_shuffle ( cross_set.begin(), cross_set.end(), p_randgenid );

  it = cross_set.begin();
  // crossover each pair from left to right
  while( it != cross_set.end())
  {
    std::pair<permutation,permutation> desc;
    crossover::type ctype;

    if(cfg.compare_operators)
    {
      switch(randid() % xop_count)
      {
        case 0: ctype = crossover::type::OX; break;
        case 1: ctype = crossover::type::CX; break;
        case 2:
        default: ctype = crossover::type::PMX; break;
      }
      desc = crossover::random_crossover(ctype, p[*it].perm, p[*(it+1)].perm);
    }
    else
    {
      desc = crossover::random_crossover(cfg.crossover_type, p[*it].perm, p[*(it+1)].perm);
    }
        
    specimen ch1, ch2;
    ch1.perm = desc.first;
    ch1.eval = evaluation(ch1.perm);
    ch1.adapt = 0.0;
    ch2.perm = desc.second;
    ch2.eval = evaluation(ch2.perm);
    ch2.adapt = 0.0;
    
    if(cfg.compare_operators && ( ((p[*it].eval + p[*(it+1)].eval) / (ch1.eval + ch2.eval)) >= 1 ) )
    {
      switch(ctype)
      {
        case crossover::type::OX: ox_count++; break;
        case crossover::type::CX: cx_count++; break;
        case crossover::type::PMX:
        default: pmx_count++; break;
      }
    }
    
    it++; it++;
    x_count++;

    new_population.push_back(ch1);
    new_population.push_back(ch2);
  }

  p.insert(p.end(), new_population.begin(), new_population.end());
}