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); */ }
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; }
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; }
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; }