const population TwoPoint::crossover(const population & mates, const Problem & problem) const { // two-point crossover population children = mates; int_dist percent(0, 100); if (chance || percent(rg.engine) < int(100 * chance)) { int_dist gene_dist(0, children[0].size() - 1); int start = gene_dist(rg.engine); int length = gene_dist(rg.engine); for (Individual & child : children) std::rotate(child.begin(), child.begin() + start, child.end()); for (int i = 0; i < length; i++) std::swap(children[0][i], children[1][i]); } // update fitnesses for (Individual & child : children) child.fitness = problem.fitness(child); return children; }
const Individual Creep::mutate(const Problem & problem, const Individual & subject) const { // basic mutation by delta distribution and chance Individual mutant = subject; // non-const copy to mutate int_dist percent(0, 100); // distribution of real delta values, scaled for problem domain real_dist delta_dist(-problem.delta * (std::abs(problem.domain_min) + std::abs(problem.domain_max)) / 2, problem.delta * (std::abs(problem.domain_min) + std::abs(problem.domain_max)) / 2); for (parameter & gene : mutant) // short circuit for problem.chance == 1 if (problem.chance || percent(rg.engine) < int(100 * problem.chance)) mutant.mutate(gene, gene + delta_dist(rg.engine)); // update fitness mutant.fitness = problem.fitness(mutant); return mutant; }