Beispiel #1
0
int init_chromosome(Chromosome **c)
{
	*c = (Chromosome *)malloc(sizeof(Chromosome));

	int i=0, j=0, s=0, complete=0, v=0;
	unsigned long seed = get_nano_seconds();
	srand(seed);

	s = rand()%SIZE + 1;
	(*c)->size = s;
	(*c)->ch = (unsigned int *)malloc(s+1);

	for (i=1; i<=s; i++) // zero base
	{
		complete = 0;
		while (!complete)
		{
			v = rand()%SIZE+1;

			for (j=1; j<=i; j++)
			{
				if ((*c)->ch[j] == v)
					break;
			}
			if (j==i+1)
			{
				(*c)->ch[i] = (unsigned int)v;
				complete = 1;
			}
		}
	}

	(*c)->p1 = 0;
	(*c)->p2 = 0;

	print_chromosome(*c);

	return 1;
}
//---------------------------------------------------------------------------
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);
}
Beispiel #3
0
int main(int argc, char *argv[])
{
	// Need to change to 3. need to remove the logging.
	if (argc != 4)
	{
		printf("Usage: ./maxcut <input data path> <output data path> <log file>\n");
		exit(-1);
	}
	
	// Need to remove when submitting.
	log_file = fopen(argv[3], "w");
	fprintf(log_file, "rate, elasped time (s), max val, avg val\n");

	start_time = get_seconds();

	in 		= fopen(argv[1], "r");
	out 	= fopen(argv[2], "w");
	int i, j, v1, v2, w;	// (v1, v2) is the vertex and w is the weight

	fscanf(in, "%d %d\n", &num_of_vertex, &num_of_edge);
	
	int edge[num_of_vertex+1][num_of_vertex+1];
	
	for (i=0; i<=SIZE; i++)
		for (j=0; j<=SIZE; j++)
			edge[i][j] = 0;

	while (fscanf(in, "%d %d %d\n", &v1, &v2, &w) != EOF)
	{
		edge[v1][v2] = w;
		edge[v2][v1] = w;
	}
	
	init_population();
	init_offsprings();
	init_cost(edge);
	sort_population();
	init_crossover();

	int p1, p2;

	while (!(stop_condition()))
	{
		generation++;
		for (i=1; i<=K; i++)
		{
			selection(&p1, &p2);
			crossover(i, p1, p2);
			mutation(i);
		}

		replacement(edge);

		sort_population();
	}

	for (i=1; i<=SIZE; i++)
	{
		if (population[N]->ch[i] == 1)
			fprintf(out, "%d ", i);
	}

	printf("max: \n");
	print_chromosome(population[N]);
	free_population();

	fclose(in);
	fclose(out);

 	printf("N: %d, K: %d, S_RATE: %lf, M_THRE: %lf, P0: %lf, POINTS: %d, K_FIT: %d, T: %lf\n", N, K, S_RATE, M_THRE, P0, POINTS, K_FIT, T);

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