Exemplo n.º 1
0
void use_sorting(int a[], int lenght)
{
	results(a, lenght);
	save_results(a, lenght);//сохраняем исходный массив в файле
	cout << "\nheap sort" << endl;
	heap_sort(a, lenght);
	results(a, lenght);//вывод на экран
	//сохранение в файл
	save_results(a, lenght);//сохраняем отсортированный массив
	delete [] a;
}
Exemplo n.º 2
0
int main(int argc, char ** argv){

  // parse arguments
  if(argc != 4){
    printf("usage: ./random problem_file execution_number num_iterations\n");
    return -1;
  }

  const char * file_name = argv[file_name_idx];
  int execution_number = atoi(argv[execution_idx]);
  long long num_processed = atoll(argv[num_processed_idx]);

  // read instance
  Instance instance = Instance::load(file_name);
  instance.preprocess();

  int n = instance.num_words();
  int best_known = instance.superstring_length();
  int random_best = INT_MAX;
  

  int start = time(0);
  #pragma omp parallel for
  for(int i = 0; i < num_processed; i++){
    Individual x(n);
    x.randomize();
    int v = instance.evaluate(&x);
    #pragma omp critical
    {
      if(v < random_best) random_best = v;

      int duration = time(0) - start;
      printf("time = %d\nbest found = %d\nbest known = %d\n", duration, random_best, best_known);
      save_results(random_best, num_processed, duration, file_name, execution_number);
    }

  }

  int duration = time(0) - start;
  printf("time = %d\nbest found = %d\nbest known = %d\n", duration, random_best, best_known);

  save_results(random_best, num_processed, duration, file_name, execution_number);

  return 0;
}
Exemplo n.º 3
0
int main(int argc, char** argv)
{
	/* declearation */
	DT *a, b;
	long arr_bytes, arr_size, p;
	int i, samples;
	double t_start, t_end, deltaT;
	/* initialization */
	b = 0.0;
	arr_bytes = 1024 * 1024 * 1024; // 1GB
	arr_size = arr_bytes/sizeof(DT);
	samples = 3;
	/* memory allocation */
#ifndef MIC
	a = (DT *)malloc(arr_bytes);
#else
	a = (DT *)_mm_malloc(arr_bytes, 64);
#endif
	if(a==NULL)
	{
		DB(RT_LVL, "array 'a' allocation failed");
	}
	fill(a, arr_size, 5.0);
#pragma omp parallel
{
	init_flush_cache_array();
}
	
	/* measurement */
	for(i=0; i<samples; i++)
	{
#pragma omp parallel
{
	flush_cache();
}
		t_start = timer();
	#pragma omp parallel for private(p) shared(a, arr_size)
		for(p=0; p<arr_size; p++)
		{
			//b += a[p];
			a[p] = b;
		}
		b = b + 1.0;
		t_end = timer();						
		if(i==(samples-1))
		{
			deltaT = t_end - t_start;
			SAVE_DATA("%lf\t", arr_bytes/deltaT)
			printf("bw: %lf\t", arr_bytes/deltaT);
		}
	}
	b = a[0] + a[arr_size-1];
	save_results(&b, 1); // save results to avoid the aggressive optimizations	
	SAVE_DATA("\n")
	
	/* post-process */
#ifndef MIC
	if(a!=NULL) free(a);
#else
	if(a!=NULL) _mm_free(a);
#endif
	return 0;
}
Exemplo n.º 4
0
/*Algoritmo Principal*/
int main(int argc, char *argv[])
{
    char name[20];// = "_kita_1";
    char archiveName[20] = "archive";
	char fitputName[20] = "fitput";
	char varputName[20] = "varput";
	char hvName[20]= "hv";
	unsigned int i, j, t;
	unsigned int fun, gen;
	clock_t  startTime, endTime;
	double duration, clocktime;
	FILE *fitfile,*varfile;
/*Parametros iniciales*/

    strcpy(name,argv[1]);
    fun = atoi(argv[2]);
    gen = atoi(argv[3]);

    printf("%s %d %d \n",name,fun,gen);

    initialize_data(fun,gen);
/*Iniciar variables*/
	initialize_memory();

	/*
	sprintf(name,"kita_1_");
	sprintf(archiveName,strcat(name,"archive.out"));
	sprintf(fitputName, strcat(name,"fitput.out"));
	sprintf(varputName, strcat(name,"varput.out"));
	sprintf(hvName,strcat(name,"hv.out"));
*/
	//fitfile = fopen(strcat(strcat(fitputName,name),".out"),"w");
	//varfile = fopen(strcat(strcat(varputName,name),".out"),"w");
	//hv = fopen(strcat(strcat(hvName,name),".out"),"w");
/* Iniciar generador de aleatorios*/
	initialize_rand();
	startTime = clock();
/* Iniciar contador de generaciones*/
	t = 0;
/* Iniciar valores de la poblacion de manera aleatoria*/
	initialize_pop();
/* Calcular velocidad inicial*/
	initialize_vel();
/* Evaluar las particulas de la poblacion*/
	evaluate();
/* Almacenar el pBest inicial (variables and valor de aptitud) de las particulas*/
	store_pbests();
/* Insertar las particulas no domindas de la poblacion en el archivo*/

	insert_nondom();
	//printf("\n%d",nondomCtr);
/*Ciclo Principal*/
	while(t <= maxgen)
	{
		//clocktime = (clock() - startTime)/(double)CLOCKS_PER_SEC;
		/*if(verbose > 0 && t%printevery==0 || t == maxgen)
		{
			fprintf(stdout,"Generation %d Time: %.2f sec\n",t,clocktime);
			fflush(stdout);
		}*/
		/*if(t%printevery==0 || t == maxgen)
		{
			fprintf(outfile,"Generation %d Time: %.2f sec\n",t,clocktime);
		}*/
    /* Calcular la nueva velocidad de cada particula en la pooblacion*/
		//printf("\n 1");
		compute_velocity();

    /* Calcular la nueva posicion de cada particula en la poblacion*/
        //printf("\n 2");
        compute_position();
    /* Mantener las particulas en la poblacion de la poblacion en el espacio de busqueda*/
		//printf("\n 3");
		maintain_particles();
    /* Pertubar las particulas en la poblacion*/
		if(t < maxgen * pMut)
			mutate(t);

    /* Evaluar las particulas en la poblacion*/
		//printf("\n 4");
		evaluate();
    /* Insertar nuevas particulas no domindas en el archivo*/
		//printf("\n 5");
		update_archive();
    /* Actualizar el pBest de las particulas en la poblacion*/
		//printf("\n 6");
		update_pbests();
    /* Escribir resultados del mejor hasta ahora*/
    //verbose > 0 && t%printevery==0 || t == maxgen
		/*if(t%printevery==0 || t == maxgen)
		{
			//fprintf(outfile, "Size of Pareto Set: %d\n", nondomCtr);
			fprintf(fitfile, "%d\n",t);
			fprintf(varfile, "%d\n",t);
			for(i = 0; i < nondomCtr; i++)
			{
			    for(j = 0; j < maxfun; j++)
                    fprintf(fitfile, "%f ", archiveFit[i][j]);
                fprintf(fitfile, "\n");
			}
			fprintf(fitfile, "\n\n");
			fflush(fitfile);
			for(i = 0; i < nondomCtr; i++)
			{
			    for(j = 0; j < maxfun; j++)
                    fprintf(varfile, "%f ", archiveVar[i][j]);
                fprintf(varfile, "\n");
			}
			fprintf(varfile, "\n\n");
			fflush(varfile);
		}*/
    /* Incrementar contador de generaciones*/
        t++;
        //printf("%d\n",t);
	}
 /* Escribir resultados en el archivo */
	save_results(strcat(strcat(archiveName,name),".out"));
	endTime = clock();
	duration = ( endTime - startTime ) / (double)CLOCKS_PER_SEC;
	fprintf(stdout, "%lf sec\n", duration);
	//fclose(fitfile);
	//fclose(varfile);
	free_memory();
	return EXIT_SUCCESS;
}
Exemplo n.º 5
0
// Required entry point
//------------------------------------------------------------------------------
int sample_main( int argc, const char** argv )
{
  
  // show console and redirect printing
  NVPWindow::sysVisibleConsole();

  const Config config( argc, argv ); 
  
  Timer timer;

  //
  // Load scene
  //
  std::cerr << "Load scene ...              "; std::cerr.flush();

  timer.start();

  bake::Scene scene;
  SceneMemory* scene_memory;
  float scene_bbox_min[] = {FLT_MAX, FLT_MAX, FLT_MAX};
  float scene_bbox_max[] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
  if (!load_scene( config.scene_filename.c_str(), scene, scene_bbox_min, scene_bbox_max, scene_memory, config.num_instances_per_mesh )) {
    std::cerr << "Failed to load scene, exiting" << std::endl;
    exit(-1);
  }

  printTimeElapsed( timer ); 

  // Print scene stats
  {
    std::cerr << "Loaded scene: " << config.scene_filename << std::endl;
    std::cerr << "\t" << scene.num_meshes << " meshes, " << scene.num_instances << " instances" << std::endl;
    size_t num_vertices = 0;
    size_t num_triangles = 0;
    for (size_t i = 0; i < scene.num_meshes; ++i) {
      num_vertices += scene.meshes[i].num_vertices;
      num_triangles += scene.meshes[i].num_triangles;
    }
    std::cerr << "\tuninstanced vertices: " << num_vertices << std::endl;
    std::cerr << "\tuninstanced triangles: " << num_triangles << std::endl;
  }

  // OptiX Prime requires all instances to have the same vertex stride
  for (size_t i = 1; i < scene.num_meshes; ++i) {
    if (scene.meshes[i].vertex_stride_bytes != scene.meshes[0].vertex_stride_bytes) {
      std::cerr << "Error: all meshes must have the same vertex stride.  Bailing.\n";
      exit(-1);
    }
  }


  //
  // Generate AO samples
  //

  std::cerr << "Minimum samples per face: " << config.min_samples_per_face << std::endl;

  std::cerr << "Generate sample points ... \n"; std::cerr.flush();

  timer.reset();
  timer.start();
  

  std::vector<size_t> num_samples_per_instance(scene.num_instances);
  const size_t total_samples = bake::distributeSamples( scene, config.min_samples_per_face, config.num_samples, &num_samples_per_instance[0] );

  bake::AOSamples ao_samples;
  allocate_ao_samples( ao_samples, total_samples );

  bake::sampleInstances( scene, &num_samples_per_instance[0], config.min_samples_per_face, ao_samples );
  
  printTimeElapsed( timer ); 

  std::cerr << "Total samples: " << total_samples << std::endl;
  {
    const int sqrt_num_rays = static_cast<int>( sqrtf( static_cast<float>( config.num_rays ) ) + .5f );
    std::cerr << "Rays per sample: " << sqrt_num_rays * sqrt_num_rays << std::endl;
    std::cerr << "Total rays: " << total_samples * sqrt_num_rays * sqrt_num_rays << std::endl;
  }

  //
  // Evaluate AO samples 
  //
  std::cerr << "Compute AO ...             "; std::cerr.flush();
  
  timer.reset();
  timer.start();

  std::vector<float> ao_values( total_samples );
  std::fill(ao_values.begin(), ao_values.end(), 0.0f);


  float scene_maxdistance;
  float scene_offset;
  {
    const float scene_scale = std::max(std::max(scene_bbox_max[0] - scene_bbox_min[0],
                                                scene_bbox_max[1] - scene_bbox_min[1]),
                                                scene_bbox_max[2] - scene_bbox_min[2]);
    scene_maxdistance = scene_scale * config.scene_maxdistance_scale;
    scene_offset = scene_scale * config.scene_offset_scale;
    if (config.scene_offset){
      scene_offset = config.scene_offset;
    }
    if (config.scene_maxdistance){
      scene_maxdistance = config.scene_maxdistance;
    }
  }

  if (config.use_ground_plane_blocker) {
    // Add blocker for ground plane (no surface samples)
    std::vector<bake::Mesh> blocker_meshes;
    std::vector<bake::Instance> blocker_instances;
    std::vector<float> plane_vertices;
    std::vector<unsigned int> plane_indices;
    make_ground_plane(scene_bbox_min, scene_bbox_max, config.ground_upaxis, config.ground_scale_factor, config.ground_offset_factor,
      scene.meshes[0].vertex_stride_bytes, 
      plane_vertices, plane_indices, blocker_meshes, blocker_instances);
    bake::Scene blockers = { &blocker_meshes[0], blocker_meshes.size(), &blocker_instances[0], blocker_instances.size() };
    bake::computeAOWithBlockers(scene, blockers,
      ao_samples, config.num_rays, scene_offset, scene_maxdistance, config.use_cpu, config.conserve_memory, &ao_values[0]);
  } else {
    bake::computeAO(scene, ao_samples, config.num_rays, scene_offset, scene_maxdistance, config.use_cpu, config.conserve_memory, &ao_values[0]);
  }
  printTimeElapsed( timer ); 

  std::cerr << "Map AO to vertices  ...    "; std::cerr.flush();

  timer.reset();
  timer.start();
  float** vertex_ao = new float*[ scene.num_instances ];
  for (size_t i = 0; i < scene.num_instances; ++i ) {
    vertex_ao[i] = new float[ scene.meshes[scene.instances[i].mesh_index].num_vertices ];
  }
  bake::mapAOToVertices( scene, &num_samples_per_instance[0], ao_samples, &ao_values[0], config.filter_mode, config.regularization_weight, vertex_ao );

  printTimeElapsed( timer ); 

  if (!config.output_filename.empty())
  {
    std::cerr << "Save vertex ao ...              "; std::cerr.flush();
    timer.reset();
    timer.start();
    bool saved = save_results(config.output_filename.c_str(), scene, vertex_ao);
    printTimeElapsed(timer);
    if (saved){
      std::cerr << "Saved vertex ao to: " << config.output_filename << std::endl;
    }
    else{
      std::cerr << "Failed to save vertex ao to: " << config.output_filename << std::endl;
    }    
  }

  if (config.use_viewer){
    //
    // Visualize results
    //
    std::cerr << "Launch viewer  ... \n" << std::endl;
    bake::view(scene.meshes, scene.num_meshes, scene.instances, scene.num_instances, vertex_ao, scene_bbox_min, scene_bbox_max);
  }

  for (size_t i = 0; i < scene.num_instances; ++i) {
    delete [] vertex_ao[i];
  }
  delete [] vertex_ao;

  destroy_ao_samples( ao_samples );

  delete scene_memory;
  
  return 1;
}
Exemplo n.º 6
0
int infogap_obs( struct opt_data *op )
{
	int i, j, ig_index, status, success = 0, count, neval_total, njac_total, no_memory = 0;
	double *opt_params, phi_min = HUGE_VAL;
	int ( *optimize_func )( struct opt_data * op );
	if( ( opt_params = ( double * ) malloc( op->pd->nOptParam * sizeof( double ) ) ) == NULL ) no_memory = 1;
	if( no_memory ) { tprintf( "Not enough memory!\n" ); return( 0 ); }
	tprintf( "\n\nInfo-gap analysis: observation step %g observation domain %g\nInfo-gap search: ", op->cd->obsstep, op->cd->obsdomain );
	if( op->cd->obsstep > DBL_EPSILON ) tprintf( "maximum\n" ); else tprintf( "minimum\n" );
	tprintf( "Number of predictions %d\n", op->preds->nTObs );
	for( i = 0; i < op->preds->nTObs; i++ )
	{
		// op->preds->obs_best are updated in mads_func.c
		if( op->cd->obsstep > DBL_EPSILON ) op->preds->obs_best[i] = -HUGE_VAL; // max search
		else op->preds->obs_best[i] = HUGE_VAL; // min search
		j = op->preds->obs_index[i];
		op->od->obs_weight[j] *= -1;
	}
	ig_index = op->preds->obs_index[0]; // first prediction is applied only
	tprintf( "Info-gap observation:\n" );
	tprintf( "%-20s: info-gap target %12g weight %12g range %12g - %12g\n", op->od->obs_id[ig_index], op->od->obs_target[ig_index], op->od->obs_weight[ig_index], op->od->obs_min[ig_index], op->od->obs_max[ig_index] );
	if( op->cd->obsstep > DBL_EPSILON ) { op->od->obs_target[ig_index] = op->od->obs_min[ig_index]; op->od->obs_min[ig_index] -= op->cd->obsstep / 2; } // obsstep is positive
	else { op->od->obs_target[ig_index] = op->od->obs_max[ig_index]; op->od->obs_max[ig_index] -= op->cd->obsstep / 2; } // obsstep is negative
	if( strncasecmp( op->cd->opt_method, "lm", 2 ) == 0 ) optimize_func = optimize_lm; // Define optimization method: LM
	else optimize_func = optimize_pso; // Define optimization method: PSO
	neval_total = njac_total = count = 0;
	while( 1 )
	{
		tprintf( "\nInfo-gap analysis #%d\n", ++count );
		tprintf( "%-20s: info-gap target %12g weight %12g range %12g - %12g\n", op->od->obs_id[ig_index], op->od->obs_target[ig_index], op->od->obs_weight[ig_index], op->od->obs_min[ig_index], op->od->obs_max[ig_index] );
		op->cd->neval = op->cd->njac = 0;
		if( op->cd->analysis_type == IGRND ) status = igrnd( op );
		else status = optimize_func( op );
		neval_total += op->cd->neval;
		njac_total += op->cd->njac;
		if( !status ) break;
		if( op->success )
		{
			for( i = 0; i < op->pd->nOptParam; i++ ) opt_params[i] = op->pd->var[op->pd->var_index[i]];
			for( i = 0; i < op->od->nTObs; i++ ) op->od->obs_best[i] = op->od->obs_current[i];
			phi_min = op->phi;
			success = 1;
		}
		tprintf( "Intermediate info-gap results for model predictions:\n" );
		tprintf( "%-20s: info-gap target %12g weight %12g range %12g - %12g\n", op->od->obs_id[ig_index], op->od->obs_target[ig_index], op->od->obs_weight[ig_index], op->od->obs_min[ig_index], op->od->obs_max[ig_index] );
		for( i = 0; i < op->preds->nTObs; i++ )
		{
			j = op->preds->obs_index[i];
			if( op->cd->obsstep > DBL_EPSILON ) tprintf( "%-20s: Current info-gap max %12g Observation step %g Observation domain %g Success %d\n", op->od->obs_id[j], op->preds->obs_best[i], op->cd->obsstep, op->cd->obsdomain, op->success );
			else                           tprintf( "%-20s: Current info-gap min %12g Observation step %g Observation domain %g Success %d\n", op->od->obs_id[j], op->preds->obs_best[i], op->cd->obsstep, op->cd->obsdomain, op->success );
		}
		if( !op->success ) break;
		if( op->cd->debug ) print_results( op, 1 );
		save_results( 1, "infogap", op, op->gd );
		op->od->obs_target[ig_index] += op->cd->obsstep;
		if( op->cd->obsstep > DBL_EPSILON ) // max search
		{
			if( op->od->obs_target[ig_index] > op->od->obs_max[ig_index] ) break;
			if( fabs( op->preds->obs_best[0] - op->od->obs_max[ig_index] ) < DBL_EPSILON ) break;
			op->od->obs_min[ig_index] += op->cd->obsstep;
			j = ( int )( ( double )( op->preds->obs_best[0] - op->od->obs_min[ig_index] + op->cd->obsstep / 2 ) / op->cd->obsstep + 1 );
			op->od->obs_target[ig_index] += op->cd->obsstep * j;
			op->od->obs_min[ig_index] += op->cd->obsstep * j;
			if( op->od->obs_target[ig_index] > op->od->obs_max[ig_index] ) op->od->obs_target[ig_index] = op->od->obs_max[ig_index];
			if( op->od->obs_min[ig_index] > op->od->obs_max[ig_index] ) op->od->obs_min[ig_index] = op->od->obs_max[ig_index];
		}
		else // min search
		{
			if( op->od->obs_target[ig_index] < op->od->obs_min[ig_index] ) break;
			if( fabs( op->preds->obs_best[0] - op->od->obs_min[ig_index] ) < DBL_EPSILON ) break;
			op->od->obs_max[ig_index] += op->cd->obsstep; // obsstep is negative
			j = ( int )( ( double )( op->od->obs_max[ig_index] - op->preds->obs_best[0] - op->cd->obsstep / 2 ) / -op->cd->obsstep + 1 ); // obsstep is negative
			op->od->obs_target[ig_index] += op->cd->obsstep * j;
			op->od->obs_max[ig_index] += op->cd->obsstep * j;
			if( op->od->obs_target[ig_index] < op->od->obs_min[ig_index] ) op->od->obs_target[ig_index] = op->od->obs_min[ig_index];
			if( op->od->obs_max[ig_index] < op->od->obs_min[ig_index] ) op->od->obs_max[ig_index] = op->od->obs_min[ig_index];
		}
	}
	op->cd->neval = neval_total; // provide the correct number of total evaluations
	op->cd->njac = njac_total; // provide the correct number of total evaluations
	if( success )
	{
		for( i = 0; i < op->pd->nOptParam; i++ ) op->cd->var[i] = op->pd->var[op->pd->var_index[i]] = op->pd->var_current[i] = op->pd->var_best[i] = opt_params[i];
		for( i = 0; i < op->od->nTObs; i++ ) op->od->obs_current[i] = op->od->obs_best[i];
		op->phi = phi_min;
		op->success = success;
	}
	else tprintf( "\nWARNING: Info-gap analysis failed to find acceptable solutions!\n" );
	tprintf( "\nInfo-gap results for model predictions:\n" );
	for( i = 0; i < op->preds->nTObs; i++ )
	{
		j = op->preds->obs_index[i];
		if( op->cd->obsstep > DBL_EPSILON ) tprintf( "%-20s: Info-gap max %12g Observation step %g Observation domain %g\n", op->od->obs_id[j], op->preds->obs_best[i], op->cd->obsstep, op->cd->obsdomain ); // max search
		else                           tprintf( "%-20s: Info-gap min %12g Observation step %g Observation domain %g\n", op->od->obs_id[j], op->preds->obs_best[i], op->cd->obsstep, op->cd->obsdomain ); // min search
		op->od->obs_target[j] = op->preds->obs_target[i];
		op->od->obs_min[j] = op->preds->obs_min[i];
		op->od->obs_max[j] = op->preds->obs_max[i];
		op->od->obs_weight[j] *= -1;
	}
	tprintf( "\n" );
	free( opt_params );
	print_results( op, 1 );
	save_results( 1, "", op, op->gd );
	return( 1 );
}
Exemplo n.º 7
0
void gmmreg_base::run(const char* f_config) {
  initialize(f_config);
  vnl_vector<double> params;
  start_registration(params);
  save_results(f_config, params);
}
Exemplo n.º 8
0
/**
 * The E-means algorithm, uses a genetic algorithm to optimize the parameters 
 * for the K-means implemetation of clustering based Lloyds clustering algorithm.
 *
 * @return        Status code, 0 for SUCCESS, 1 for ERROR
 */
int emeans(void)
{
    gsl_matrix *data = NULL,
               *bounds = NULL,
               *parent1 = NULL,
               *parent2 = NULL,
               **population = NULL,
               **new_population = NULL,
               ***clusters = NULL;
    int status = SUCCESS;
    double fitness[size],
           probability[size];

    // Initialize the PRNG
    pcg32_random_t rng;
    int rounds = 5;
    pcg32_srandom_r(&rng, time(NULL) ^ (intptr_t)&printf, (intptr_t)&rounds);

    // Allocate memory and load the data
    data = gsl_matrix_alloc(data_rows, data_cols);
    bounds = gsl_matrix_alloc(data_cols, 2);
    parent1 = gsl_matrix_alloc(n_clusters, data_cols);
    parent2 = gsl_matrix_alloc(n_clusters, data_cols);
    population = (gsl_matrix **)calloc(size, sizeof(gsl_matrix **));
    new_population = (gsl_matrix **)calloc(size, sizeof(gsl_matrix **));
    clusters = (gsl_matrix ***)calloc(size, sizeof(gsl_matrix ***));

    for (int i = 0; i < (int)size; ++i)
    {
        clusters[i] = (gsl_matrix **)calloc(n_clusters, sizeof(gsl_matrix **));
        population[i] = gsl_matrix_alloc(n_clusters, data_cols);
        new_population[i] = gsl_matrix_alloc(n_clusters, data_cols);
    }
    if ((status = load_data(data_file, data)) != SUCCESS)
    {   
        fprintf(stderr, RED "Unable to load data!\n" RESET);
        status = ERROR;
        goto free;
    }

    // Calculate the bounds of the data
    calc_bounds(data, bounds);

    // Generate the initial population
    printf(CYAN "Generating initial population...\n" RESET);
    for (int i = 0; i < (int)size; ++i)
    {
        random_centroids(population[i], bounds, &rng);
    }

    // Perform the Genetic Algorithm
    for (int iter = 0; iter < max_iter; ++iter)
    {
        // Compute the fitness of each chromosome
        for (int i = 0; i < (int)size; ++i)
        {
            lloyd_defined(trials, population[i], data, n_clusters, clusters[i]);
            fitness[i] = dunn_index(population[i], n_clusters, clusters[i]);
            if (VERBOSE == 1)
                printf(CYAN "chromsome[%d], fitness: %10.6f\n" RESET, i, fitness[i]);
        }

        // Generate the probabilities for roulette wheel selection
        gen_probability(size, fitness, probability);

        // Save the results if there is a new best solution
        save_results(fitness_file, centroids_file, cluster_file, size, fitness, 
                     population, n_clusters, clusters);

        // Perform roulette wheel selection and GA operators
        if (VERBOSE == 1)
            printf(CYAN "Executing roulette wheel selection...\n" RESET);

        // Select parents from the population and perform genetic operators
        for (int i = 0; i < size; i += 2)
        {
            // Select parents
            for (int j = 0, idx = 0; j < 2; ++j)
            {
                idx = select_parent(size, probability, &rng);
                if (VERBOSE == 1)
                    printf(CYAN "Parent %d selected as chromsome %d from population\n" RESET, j, idx);

                if (j == 0)
                    gsl_matrix_memcpy(parent1, population[idx]);
                else
                    gsl_matrix_memcpy(parent2, population[idx]);
            }

            // Perform crossover and mutation with specified probabilities
            if (VERBOSE == 1)
                printf(CYAN "Performing crossover...\n" RESET);
            if (pcg32_random_r(&rng) / (double)UINT32_MAX <= c_rate)
            {
                crossover(parent1, parent2, &rng);
            }

            if (VERBOSE == 1)
                printf(CYAN "Performing background mutation...\n" RESET);
            for (int j = 0; j < 2; ++j)
            {
                if (pcg32_random_r(&rng) / (double)UINT32_MAX <= m_rate)
                {
                    if (j == 0)
                        mutate(parent1, bounds, &rng);
                    else
                        mutate(parent2, bounds, &rng);
                }
            }

            // Copy each parent to the new population
            if (VERBOSE == 1)
                printf(CYAN "Copying parents to new population...\n" RESET);
            gsl_matrix_memcpy(new_population[i], parent1);
            gsl_matrix_memcpy(new_population[i+1], parent2);
        }

        // Copy the new population to the next population
        if (VERBOSE == 1)
            printf(CYAN "Copying current population as new population\n" RESET);

        for (int i = 0; i < size; ++i)
        {
            gsl_matrix_memcpy(population[i], new_population[i]);
        }

        // Check if stop signal, terminate if present
        if (access("./stop", F_OK) != -1)
        {
            printf(YELLOW "Stop signal received, shutting down!\n" RESET);
            remove("./stop");
            break;
        }

    }
    printf(GREEN "Finished executing E-means, shutting down!\n" RESET);

free:
    for (int i = 0; i < (int)size; ++i)
    {
        for (int j = 0; j < n_clusters; ++j)
        {
            gsl_matrix_free(clusters[i][j]);
        }
        free(clusters[i]);
    }
    free(clusters);
    for (int i = 0; i < (int)size; ++i)
    {
        gsl_matrix_free(population[i]);
        gsl_matrix_free(new_population[i]);
    }
    free(population);
    free(new_population);
    gsl_matrix_free(data);
    gsl_matrix_free(bounds);
    return status;
}