void crossover (int j) { struct node *p1_node = NULL; struct node *p2_node = NULL; struct node *t1_node = NULL; int point1 = 0; int point2 = 0; int p1 = tournament_selection(); int p2 = p1; int i = 0; if(number_of_nondominated > 1) while (p1 == p2) p2 = tournament_selection(); point1 = (rand() % population[p1].size) + 1; point2 = (rand() % population[p2].size) + 1; population[j].root = copy_tree(population[p1].root); p1_node = find_node(point1,&i,population[j].root); i = 0; p2_node = find_node(point2,&i,population[p2].root); t1_node = copy_tree(p2_node); destroy_tree(p1_node -> left); destroy_tree(p1_node -> right); p1_node -> key_type = t1_node -> key_type; p1_node -> key_value = t1_node -> key_value; p1_node -> left = t1_node -> left; p1_node -> right = t1_node -> right; free(t1_node); }
void mutate (int j) { int p = tournament_selection(); population[j].root = copy_tree(population[p].root); int ind = (rand() % get_tree_size(population[j].root)) + 1; struct node *n_node = NULL; struct node *e_node = NULL; if ( ind == 1 ) { destroy_tree(population[j].root); population[j].root = create_random_node(); population[j].age = 0; } else { int i = 0; n_node = find_node(ind,&i,population[j].root); e_node = create_random_node(); destroy_tree(n_node -> left); destroy_tree(n_node -> right); n_node -> key_type = e_node -> key_type; n_node -> key_value = e_node -> key_value; n_node -> left = e_node -> left; n_node -> right = e_node -> right; free(e_node); } }
void Generation::produce_offspring(genetic_parameters const& genetic_param, std::vector<bound> const& param_bounds) { // Initialize random generator std::random_device rd; std::array<unsigned int, std::mt19937::state_size> seed_data; std::generate_n(seed_data.begin(), seed_data.size(), std::ref(rd)); std::seed_seq seq(std::begin(seed_data), std::end(seed_data)); std::mt19937 engine(seq); // Check if the number of chromosomes is even size_t pairs(0); if (size % 2 == 0) { pairs = size / 2; } else { pairs = (size + 1) / 2; } // Select the pairs of parents and produce an offspring for (size_t i = 0; i < pairs; ++i) { // Select parents via tournament selection Chromosome parent1 = chromosomes[tournament_selection(engine)]; Chromosome parent2 = chromosomes[tournament_selection(engine)]; // Crossover parents crossover_chromosomes(parent1, parent2, genetic_param.prob_crossover, engine); // Mutate parents mutate_chromosome(parent1, genetic_param.prob_mutation, param_bounds, engine); mutate_chromosome(parent2, genetic_param.prob_mutation, param_bounds, engine); // Save new chromosomes offspring.push_back(parent1); if (2 * (i + 1) <= size) { offspring.push_back(parent2); } } // Save new generation chromosomes = offspring; offspring.clear(); }
void evolve_one_subpopulation(int *current_subpop_index, t_chromosome ** sub_populations, int generation_index, t_parameters *params, t_graph *training_graphs, int num_training_graphs, int num_variables, double* vars_values) #endif { int pop_index = 0; while (*current_subpop_index < params->num_sub_populations) {// still more subpopulations to evolve? #ifdef USE_THREADS while (!mutex->try_lock()) {}// create a lock so that multiple threads will not evolve the same sub population pop_index = *current_subpop_index; (*current_subpop_index)++; mutex->unlock(); #else pop_index = *current_subpop_index; (*current_subpop_index)++; #endif // pop_index is the index of the subpopulation evolved by the current thread if (pop_index < params->num_sub_populations) { t_chromosome *a_sub_population = sub_populations[pop_index]; t_chromosome offspring1, offspring2; allocate_chromosome(offspring1, *params); allocate_chromosome(offspring2, *params); double *partial_values_array = new double[params->code_length]; if (generation_index == 0) { for (int i = 0; i < params->sub_population_size; i++) { generate_random_chromosome(a_sub_population[i], *params, num_variables); a_sub_population[i].fitness = compute_fitness(a_sub_population[i], training_graphs, num_training_graphs, num_variables, vars_values, partial_values_array); } // sort ascendingly by fitness inside this population qsort((void *)a_sub_population, params->sub_population_size, sizeof(a_sub_population[0]), sort_function); } else // next generations for (int k = 0; k < params->sub_population_size; k += 2) { // we increase by 2 because at each step we create 2 offspring // choose the parents using binary tournament int r1 = tournament_selection(a_sub_population, params->sub_population_size, 2); int r2 = tournament_selection(a_sub_population, params->sub_population_size, 2); // crossover double p_0_1 = rand() / double(RAND_MAX); // a random number between 0 and 1 if (p_0_1 < params->crossover_probability) one_cut_point_crossover(a_sub_population[r1], a_sub_population[r2], *params, offspring1, offspring2); else {// no crossover so the offspring are a copy of the parents copy_individual(offspring1, a_sub_population[r1], *params); copy_individual(offspring2, a_sub_population[r2], *params); } // mutate the result and compute fitness mutation(offspring1, *params, num_variables); offspring1.fitness = compute_fitness(offspring1, training_graphs, num_training_graphs, num_variables, vars_values, partial_values_array); // mutate the other offspring too mutation(offspring2, *params, num_variables); offspring2.fitness = compute_fitness(offspring2, training_graphs, num_training_graphs, num_variables, vars_values, partial_values_array); // replace the worst in the population if (offspring1.fitness < a_sub_population[params->sub_population_size - 1].fitness) { copy_individual(a_sub_population[params->sub_population_size - 1], offspring1, *params); qsort((void *)a_sub_population, params->sub_population_size, sizeof(a_sub_population[0]), sort_function); } if (offspring2.fitness < a_sub_population[params->sub_population_size - 1].fitness) { copy_individual(a_sub_population[params->sub_population_size - 1], offspring2, *params); qsort((void *)a_sub_population, params->sub_population_size, sizeof(a_sub_population[0]), sort_function); } } delete_chromosome(offspring1); delete_chromosome(offspring2); delete[] partial_values_array; } } }
//--------------------------------------------------------------------------- void start_steady_state_mep(parameters ¶ms, double **training_data, double* target, int num_training_data, int num_variables) // Steady-State { // a steady state approach: // we work with 1 population // newly created individuals will replace the worst existing ones (only if they are better). // allocate memory chromosome *population; population = new chromosome[params.pop_size]; for (int i = 0; i < params.pop_size; i++) allocate_chromosome(population[i], params); chromosome offspring1, offspring2; allocate_chromosome(offspring1, params); allocate_chromosome(offspring2, params); double ** eval_matrix; allocate_partial_expression_values(eval_matrix, num_training_data, params.code_length); // initialize for (int i = 0; i < params.pop_size; i++) { generate_random_chromosome(population[i], params, num_variables); if (params.problem_type == PROBLEM_TYPE_REGRESSION) fitness_regression(population[i], params.code_length, num_variables, num_training_data, training_data, target, eval_matrix); else fitness_classification(population[i], params.code_length, num_variables, params.num_classes, num_training_data, training_data, target, eval_matrix); } // sort ascendingly by fitness qsort((void *)population, params.pop_size, sizeof(population[0]), sort_function); printf("generation %d, best fitness = %lf\n", 0, population[0].fitness); for (int g = 1; g < params.num_generations; g++) {// for each generation for (int k = 0; k < params.pop_size; k += 2) { // choose the parents using binary tournament int r1 = tournament_selection(population, params.pop_size, 2); int r2 = tournament_selection(population, params.pop_size, 2); // crossover double p = rand() / double(RAND_MAX); if (p < params.crossover_probability) one_cut_point_crossover(population[r1], population[r2], params, offspring1, offspring2); else {// no crossover so the offspring are a copy of the parents copy_individual(offspring1, population[r1], params); copy_individual(offspring2, population[r2], params); } // mutate the result and compute fitness mutation(offspring1, params, num_variables); if (params.problem_type == PROBLEM_TYPE_REGRESSION) fitness_regression(offspring1, params.code_length, num_variables, num_training_data, training_data, target, eval_matrix); else fitness_classification(offspring1, params.code_length, num_variables, params.num_classes, num_training_data, training_data, target, eval_matrix); // mutate the other offspring and compute fitness mutation(offspring2, params, num_variables); if (params.problem_type == PROBLEM_TYPE_REGRESSION) fitness_regression(offspring2, params.code_length, num_variables, num_training_data, training_data, target, eval_matrix); else fitness_classification(offspring2, params.code_length, num_variables, params.num_classes, num_training_data, training_data, target, eval_matrix); // replace the worst in the population if (offspring1.fitness < population[params.pop_size - 1].fitness) { copy_individual(population[params.pop_size - 1], offspring1, params); qsort((void *)population, params.pop_size, sizeof(population[0]), sort_function); } if (offspring2.fitness < population[params.pop_size - 1].fitness) { copy_individual(population[params.pop_size - 1], offspring2, params); qsort((void *)population, params.pop_size, sizeof(population[0]), sort_function); } } printf("generation %d, best fitness = %lf\n", g, population[0].fitness); } // print best chromosome print_chromosome(population[0], params, num_variables); // free memory delete_chromosome(offspring1); delete_chromosome(offspring2); for (int i = 0; i < params.pop_size; i++) delete_chromosome(population[i]); delete[] population; delete_data(training_data, target, num_training_data); delete_partial_expression_values(eval_matrix, params.code_length); }
int main() { // Initial population std::vector<grid> population; int largest = 0; for(int i = 0; i < 100; ++i) { grid g; while(g.can_move()) { g.action(rand_action()); } population.emplace_back(g); } for(unsigned int i = 0; i < 100000; ++i) { unsigned int parent_a = tournament_selection(population); unsigned int parent_b = tournament_selection(population); grid child_a; grid child_b; one_point_crossover(population.at(parent_a).actions(), population.at(parent_b).actions(), child_a, child_b); population.emplace_back(child_a); population.emplace_back(child_b); sort_population(population); population.pop_back(); population.pop_back(); if(largest < population.at(0).score()) { largest = population.at(0).score(); std::cout << largest << std::endl; } sort_population_random(population); } sort_population(population); population.at(0).print(); for(auto const& p : population) { std::cout << p.score() << std::endl; } return 0; }
//-------------------------------------------------------------------- void start_steady_state_ga(int pop_size, int num_gens, int num_dims, int num_bits_per_dimension, double pcross, double pm, double min_x, double max_x) // Steady-State genetic algorithm // each step: // pick 2 parents, mate them, // mutate the offspring // and replace the worst in the population // (only if offspring are better) { // allocate memory b_chromosome *population; population = (b_chromosome*)malloc(pop_size * sizeof(b_chromosome)); for (int i = 0; i < pop_size; i++) population[i].x = (char*)malloc(num_dims * num_bits_per_dimension); b_chromosome offspring1, offspring2; offspring1.x = (char*)malloc(num_dims * num_bits_per_dimension); offspring2.x = (char*)malloc(num_dims * num_bits_per_dimension); // initialize for (int i = 0; i < pop_size; i++) { generate_random(population[i], num_dims, num_bits_per_dimension); compute_fitness(&population[i], num_dims, num_bits_per_dimension, min_x, max_x); } qsort((void *)population, pop_size, sizeof(population[0]), sort_function); printf("generation 0\n"); // print the best from generation 0 print_chromosome(&population[0], num_dims, num_bits_per_dimension, min_x, max_x); for (int g = 1; g < num_gens; g++) { for (int k = 0; k < pop_size; k += 2) { // choose the parents using binary tournament int r1 = tournament_selection(2, population, pop_size); int r2 = tournament_selection(2, population, pop_size); // crossover double p = rand() / double(RAND_MAX); if (p < pcross) one_cut_point_crossover(population[r1], population[r2], offspring1, offspring2, num_dims, num_bits_per_dimension); else { copy_individual(&offspring1, population[r1], num_dims, num_bits_per_dimension); copy_individual(&offspring2, population[r2], num_dims, num_bits_per_dimension); } // mutate the result and compute its fitness mutation(offspring1, num_dims, num_bits_per_dimension, pm); compute_fitness(&offspring1, num_dims, num_bits_per_dimension, min_x, max_x); mutation(offspring2, num_dims, num_bits_per_dimension, pm); compute_fitness(&offspring2, num_dims, num_bits_per_dimension, min_x, max_x); // are offspring better than the worst ? if (offspring1.fitness < population[pop_size - 1].fitness) { copy_individual(&population[pop_size - 1], offspring1, num_dims, num_bits_per_dimension); qsort((void *)population, pop_size, sizeof(population[0]), sort_function); } if (offspring2.fitness < population[pop_size - 1].fitness) { copy_individual(&population[pop_size - 1], offspring2, num_dims, num_bits_per_dimension); qsort((void *)population, pop_size, sizeof(population[0]), sort_function); } } printf("generation %d\n", g); print_chromosome(&population[0], num_dims, num_bits_per_dimension, min_x, max_x); } // free memory free(offspring1.x); free(offspring2.x); for (int i = 0; i < pop_size; i++) free(population[i].x); free(population); }