Example #1
0
void _mutation(struct ia_circles **generation)
{
	if(ia_cfg.quit) {
		return;
	}
	int idx;
	printfi("mutation round\n");
	for(idx = 0; idx < GEN_SIZE; idx++) {
		printfl(IA_INFO, "mutating %d\n", idx);
		_mutate(generation[idx]);
		sort_circles(generation[idx]);
		refresh_circles(generation[idx]);
	}
	/*
	_mutate(ia_cfg.seed1);
	_mutate(ia_cfg.seed2);
	_mutate(ia_cfg.seed3);
	sort_circles(ia_cfg.seed1);
	sort_circles(ia_cfg.seed2);
	sort_circles(ia_cfg.seed3);
	refresh_circles(ia_cfg.seed1);
	refresh_circles(ia_cfg.seed2);
	refresh_circles(ia_cfg.seed3);
	*/
}
Example #2
0
static struct ia_circles *_better(struct ia_circles *orig) {
	struct ia_circles *better = clone_circles(orig);
	if(ia_cfg.cur_gen > 0) {
		printfi("extinction: %d\n", ia_cfg.extinction);
		_mutate(better);
		refresh_circles(better);
	}
	return better;
}
Example #3
0
static struct ia_circles *_crossover(struct ia_circles *c1,
    struct ia_circles *c2, struct ia_circles *c3)
{
	const int crossover_num = 10;
	struct ia_circles *c1c = clone_circles(c1);
	struct ia_circles *c2c = clone_circles(c2);
	struct ia_circles *c3c = clone_circles(c3);
	refresh_circles(c1c);
	refresh_circles(c2c);
	refresh_circles(c3c);
	struct ia_circles *ret = NULL;
	struct ia_circles **best_candidates = calloc(crossover_num,
	    sizeof(struct ia_circles *));

	// for now, between 10% and 20% will get swapped
	int *indices = NULL, idx;
	int indices_num = get_rand() % (c1c->num_circles / 10);
	indices_num += c1c->num_circles / 10;
	indices = malloc(indices_num * sizeof(int)); // do null check at some point

	for(idx = 0; idx < indices_num; idx++) {
		indices[idx] = get_rand() % c1c->num_circles;
	}

        for(idx = 0; idx < crossover_num; idx++) {
		best_candidates[idx] = _cross_helper(c1c, c2c, indices, indices_num);
	}
	qsort(best_candidates, crossover_num, sizeof(struct ia_circles *),
	    (__compar_fn_t)_score_compare2);

	ret = clone_circles(best_candidates[0]);
	for(idx = 0; idx < crossover_num; idx++) {
		free_circles(best_candidates[idx]);
	}
	free_circles(c1c);
	free(c1c);
	c1c = ret;
	for(idx = 0; idx < indices_num; idx++) {
		indices[idx] = get_rand() % c1c->num_circles;
	}
        for(idx = 0; idx < crossover_num; idx++) {
		best_candidates[idx] = _cross_helper(c1c, c3c, indices, indices_num);
	}
	qsort(best_candidates, crossover_num, sizeof(struct ia_circles *),
	    (__compar_fn_t)_score_compare2);

	ret = clone_circles(best_candidates[0]);
	for(idx = 0; idx < crossover_num; idx++) {
		free_circles(best_candidates[idx]);
	}

	free(best_candidates);
	free_circles(c1c);
	free(c1c);
	free_circles(c2c);
	free(c2c);
	free_circles(c3c);
	free(c3c);
	free(indices);

        if(ia_cfg.cur_gen > (MAGIC_START / 2)) {
		bool sick = get_rand() % MAX(1,
		    (uint32_t)((35021 - ((ia_cfg.cur_gen + 1) / 10)) /
		    (uint32_t)_fib((log2(ia_cfg.cur_gen + 1)
		        + 1)))) == 0;
		//if(sick || _redo_count > 1) {
		if(sick) {
			for(int jdx = 0; jdx < _redo_count; jdx++) {
				_seed_mutate(ret);
			}
			
#if 0			
			if(_redo_count < MAX_REDO / 2) {
				for(int jdx = 0; jdx < _redo_count; jdx++) {
					_seed_mutate(ret);
				}
			} else {
				_mutate(ret);
			}
#endif
		}
	}
	refresh_circles(ret);

	for(idx = 0; idx < ret->num_circles; idx++) {
		ret->circles[idx].crossed_rounds_ago++;
	}

#if 0
	if(get_rand() % 51503 == 4) {
		printf("we have a winner\n");
		while(ret->img->score > MIN(c1->img->score, c2->img->score)) {
			_mutate(ret);
			refresh_circles(ret);
		}
	}
#endif
	ret->mother_index = c1->my_index;
	ret->father_index = c2->my_index;
	ret->father2_index = c3->my_index;

	return ret;
}
Example #4
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;
  }