//---------------------------------------------------------------------------
void start_steady_state(t_parameters &params, t_graph *training_graphs, int num_training_graphs, t_graph *validation_graphs, int num_validation_graphs, int num_variables, int num_procs, int current_proc_id)
{

	int size_to_send = params.code_length * sizeof(t_code3) + params.num_constants * 20 + 20;
	char *s_source = new char[size_to_send];
	char *s_dest = new char[size_to_send];

	t_chromosome receive_chromosome;
	allocate_chromosome(receive_chromosome, params);


	// a steady state model - 
	// Newly created inviduals replace the worst ones (if the offspring are better) in the same (sub) population.

	// allocate memory for all sub populations
	t_chromosome **sub_populations; // an array of sub populations
	sub_populations = new t_chromosome*[params.num_sub_populations];
	for (int p = 0; p < params.num_sub_populations; p++) {
		sub_populations[p] = new t_chromosome[params.sub_population_size];
		for (int i = 0; i < params.sub_population_size; i++)
			allocate_chromosome(sub_populations[p][i], params); // allocate each individual in the subpopulation 
	}
#ifdef USE_THREADS
	// allocate memory
	double** vars_values = new double*[params.num_threads];
	for (int t = 0; t < params.num_threads; t++)
		vars_values[t] = new double[num_variables];

	// an array of threads. Each sub population is evolved by a thread
	std::thread **mep_threads = new std::thread*[params.num_threads];
	// we create a fixed number of threads and each thread will take and evolve one subpopulation, then it will take another one
	std::mutex mutex;
	// we need a mutex to make sure that the same subpopulation will not be evolved twice by different threads
#else
	double* vars_values = new double[num_variables];
#endif

	t_chromosome best_validation;
	allocate_chromosome(best_validation, params);
	double best_validation_fitness = DBL_MAX;

	// evolve for a fixed number of generations
	for (int generation = 0; generation < params.num_generations; generation++) { // for each generation

#ifdef USE_THREADS
		int current_subpop_index = 0;
		for (int t = 0; t < params.num_threads; t++)
			mep_threads[t] = new std::thread(evolve_one_subpopulation, &current_subpop_index, &mutex, sub_populations, generation, &params, training_graphs, num_training_graphs, num_variables, vars_values[t]);

		for (int t = 0; t < params.num_threads; t++) {
			mep_threads[t]->join();
			delete mep_threads[t];
		}
#else
		//for (int p = 0; p < params.num_sub_populations; p++)
		int p = 0;
		evolve_one_subpopulation(&p, sub_populations, generation, &params, training_graphs, num_training_graphs, num_variables, vars_values);
#endif
		// find the best individual
		int best_individual_subpop_index = 0; // the index of the subpopulation containing the best invidual

		for (int p = 1; p < params.num_sub_populations; p++)
			if (sub_populations[p][0].fitness < sub_populations[best_individual_subpop_index][0].fitness)
				best_individual_subpop_index = p;

		double *partial_values_array = new double[params.code_length];

		sub_populations[best_individual_subpop_index][0].simplify(params.code_length);
		double current_validation_fitness = compute_fitness(sub_populations[best_individual_subpop_index][0], validation_graphs, num_validation_graphs, num_variables, vars_values, partial_values_array);

		if (!generation || generation && current_validation_fitness < best_validation_fitness) {
			best_validation_fitness = current_validation_fitness;
			copy_individual(best_validation, sub_populations[best_individual_subpop_index][0], params);
		}
		delete[] partial_values_array;

		printf("proc_id=%d, generation=%d, best training =%lf best validation =%lf\n", current_proc_id, generation, sub_populations[best_individual_subpop_index][0].fitness, best_validation_fitness);

		if (current_proc_id == 0) {
			FILE* f = fopen("tst_log.txt", "a");
			fprintf(f, "proc_id=%d, generation=%d, best=%lf\n", current_proc_id, generation, sub_populations[best_individual_subpop_index][0].fitness);
			fclose(f);
		}

		// now copy one individual from one population to the next one.
		// the copied invidual will replace the worst in the next one (if is better)

		for (int p = 0; p < params.num_sub_populations; p++) {
			int  k = rand() % params.sub_population_size;// the individual to be copied
			// replace the worst in the next population (p + 1) - only if is better
			int index_next_pop = (p + 1) % params.num_sub_populations; // index of the next subpopulation (taken in circular order)
			if (sub_populations[p][k].fitness < sub_populations[index_next_pop][params.sub_population_size - 1].fitness) {
				copy_individual(sub_populations[index_next_pop][params.sub_population_size - 1], sub_populations[p][k], params);
				qsort((void *)sub_populations[index_next_pop], params.sub_population_size, sizeof(sub_populations[0][0]), sort_function);
			}
		}

#ifdef USE_MPI
		// here I have to copy few individuals from one process to another process
		for (int i = 0; i < 1; i++) {
			int source_sub_population_index = rand() % params.num_sub_populations;
			int chromosome_index = rand() % params.sub_population_size;
			int tag = 0;

			sub_populations[source_sub_population_index][chromosome_index].to_string(s_dest, params.code_length, params.num_constants);
			MPI_Send((void*)s_dest, size_to_send, MPI_CHAR, (current_proc_id + 1) % num_procs, tag, MPI_COMM_WORLD);

			MPI_Status status;
			int flag;
			MPI_Iprobe(!current_proc_id ? num_procs - 1 : current_proc_id - 1, tag, MPI_COMM_WORLD, &flag, &status);
			if (flag) {
				MPI_Recv(s_source, size_to_send, MPI_CHAR, !current_proc_id ? num_procs - 1 : current_proc_id - 1, tag, MPI_COMM_WORLD, &status);
				receive_chromosome.from_string(s_source, params.code_length, params.num_constants);

				int dest_sub_population_index = rand() % params.num_sub_populations;
				if (receive_chromosome.fitness < sub_populations[dest_sub_population_index][params.sub_population_size - 1].fitness) {
					copy_individual(sub_populations[dest_sub_population_index][params.sub_population_size - 1], receive_chromosome, params);
					qsort((void *)sub_populations[dest_sub_population_index], params.sub_population_size, sizeof(sub_populations[0][0]), sort_function);
				}
			}
		}


#endif
	}

#ifdef USE_THREADS
	delete[] mep_threads;
#endif
	// print best t_chromosome
	// any of them can be printed because if we allow enough generations, the populations will become identical
	print_chromosome(best_validation, params, num_variables);
	best_validation.to_file_simplified("best.txt", params.code_length, params.num_constants);

	// free memory

	for (int p = 0; p < params.num_sub_populations; p++) {
		for (int i = 0; i < params.sub_population_size; i++)
			delete_chromosome(sub_populations[p][i]);
		delete[] sub_populations[p];
	}
	delete[] sub_populations;

#ifdef USE_THREADS
	for (int t = 0; t < params.num_threads; t++)
		delete[] vars_values[t];
	delete[] vars_values;
#endif

	delete[] s_dest;
	delete[] s_source;

	delete_chromosome(receive_chromosome);
	delete_chromosome(best_validation);
}
Exemple #2
0
int main()

{
  
  BT bt;
  
  bt=get_memaddr("core");
  
  int i;
  
  /* testing for the data structure BST SCORE_SHEET*/

  CHROMO c1,c2,c3,c4,c5;
  sprintf(c1.filename,"winkeyd.exe");
  c1.score=6;

  sprintf(c2.filename,"this is c2");
  c2.score=8;

  sprintf(c3.filename,"x1.mp3");
  c3.score=3;

  sprintf(c4.filename,"x2.mp3");
  c4.score=40;

  sprintf(c5.filename,"x3.mp3");
  c5.score=60;

  SCORE_SHEET *ss=init_list();

  ss=insert_chromosome(ss,c1);

  ss=insert_chromosome(ss,c2);

  ss=insert_chromosome(ss,c3);

  ss=insert_chromosome(ss,c4);

  ss=insert_chromosome(ss,c5);

  printf("the sum of scores is: %d\n",sum_of_scores(ss)); 

  ss=delete_chromosome(ss,c1);

  /*selection of individual*/

  //print_list(ss);

  free(ss);

  char **files;
  int noFiles=3;

  files=(char **)malloc(noFiles*sizeof(char *));
  
  for(i=0;i<noFiles;i++)
    files[i]=(char *)malloc(20*sizeof(char));

  strcpy(files[0],"x1.mp3");
  strcpy(files[1],"x2.mp3"); 
  strcpy(files[2],"x3.mp3");

  POPULATION pop=initialize("avgscan","mp3",files,noFiles,bt);

  
  print_list(pop);   
  return 0;	
}
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);
}