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 &params, 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);
}
Exemple #6
0
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);
}