/* create a mutated individual */
individual* mutate_individual( individual* i, int degree ) {
	individual* mutant;
	mutant = copy_individual( i );
	mutant->correct = -1;
	mutant->age = 0;
	mutant->length = 0;


	int c, mutation_location, new_value;
	/* there will be degree value changes to the copied individual,
	   but there is no guarantee that there will be degree differences
		 from the original since a single value can be changed multiple
		 times
	*/
	
	for( c = 0; c < degree; c++ ) {

		mutation_location = randint( mutant->length );
		new_value = randint( mutant->length );
		while( new_value == mutant->list[mutation_location] ) {
			new_value = randint( mutant->length );
		}
		mutant->list[mutation_location] = new_value;
	}
	return mutant;
}
Ejemplo n.º 2
0
void copy_population(Population * from, Population * to)
{
	for(int i = 0; i < POPULATION_SIZE; ++i)
	{
		copy_individual(&from->individuals[i], &to->individuals[i]);
	}
}
Ejemplo n.º 3
0
void selection_by_tournament(Population * from, Population * to)
{
	int index1, index2;
	for(int i = 0; i < POPULATION_SIZE; ++i)
	{
		index1 = rand() % POPULATION_SIZE;
		index2 = rand() % POPULATION_SIZE;

		if(from->individuals[index1].fitness >= from->individuals[index2].fitness)
		{
			copy_individual(&from->individuals[index1], &to->individuals[i]);
		} else
		{
			copy_individual(&from->individuals[index2], &to->individuals[i]);
		}
	}
}
Ejemplo n.º 4
0
/**
 * mutate the individual with a new one taken from the population
 * but just 1 mutation-step away
 * 
 * @return -1 if no new individual can be found which is 1 gene away
 */
short mutate_1gene(int *individual, int *population) {
		int test_mutation[GENOTYPE_LENGTH];

		// make a backup copy
		copy_individual(individual, test_mutation);

		// breed the possible population
		int max_mutations = GENOTYPE_LENGTH-1;
		int mutations[max_mutations][GENOTYPE_LENGTH];
		int possible_mutations = 0 ;


		int i = 0, j;

		// for every bit of the original individual
		for ( j = 0 ; j < GENOTYPE_LENGTH ; j++ )
		{
				// mutate a specific gene
				bitflip1(test_mutation, j);
				// check if such individual has been 
				// tested already for fitness
				if ( population[hash(test_mutation)] == 0 )
				{
						// if it's not yet tested put into the pool 
						// of possible mutations
						copy_individual(test_mutation, mutations[i]);
						i++;
				}
				// get the original individual back
				copy_individual(individual, test_mutation);
		}

		if ( i == 0 )
				// no new individual can be found
				return -1;

		// select one random "new" individual
		int new_individual_index = rand() % i;

		// that's our man
		copy_individual(mutations[new_individual_index], individual);

		return 0;
}
//---------------------------------------------------------------------------
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);
}
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;
		}
	}
}
Ejemplo n.º 7
0
/* Performs variation. */
int variate(int *selected, int *result_ids)
{
     int result, i, k;

     result = 1;

     /* copying all individuals from selected */
     for(i = 0; i < mu; i++)
     {
          result_ids[i] = 
               add_individual(copy_individual(get_individual(selected[i])));
          if(result_ids[i] == -1)
          {
               log_to_file(log_file, __FILE__, __LINE__,
                           "copying + adding failed");
               return (1);
          }
     }
 
     /* if odd number of individuals, last one is
        left as is */
     if((((double)mu/2) - (int)(mu/2)) != 0) k = mu - 1; 
     else k = mu;

     /* do recombination */
     for(i = 0; i < k; i+= 2)
     {  
          if (drand(1) <= individual_recombination_probability)
          {
               if (variable_swap_probability > 0)
               {
                    result = uniform_crossover
                      (get_individual(result_ids[i]),
                       get_individual(result_ids[i + 1]));
                    if (result != 0)
                         log_to_file(log_file, __FILE__, 
                                     __LINE__, "recombination failed!");
               }

               if (variable_recombination_probability > 0)
               {
                    result = sbx
                      (get_individual(result_ids[i]), 
                       get_individual(result_ids[i + 1]));
                    if (result != 0)
                         log_to_file(log_file, __FILE__, 
                                     __LINE__, "recombination failed!");
               }
          }
     }
     
     /* do mutation */
     for(i = 0; i < mu; i++)
     {
          if (drand(1) <= individual_mutation_probability)
          { 
               if (variable_mutation_probability > 0)
               {
                    result = mutation(get_individual(result_ids[i]));
                    if(result != 0)
                      log_to_file(log_file, __FILE__, __LINE__,
                                  "mutation failed!");
               }
          }
     }
     
     /* do evaluation */
     for(i = 0; i < mu; i++)
     {
          int result;
          result = eval(get_individual(result_ids[i]));
     }
     
     return (0);
}
Ejemplo n.º 8
0
/**********************************************************************
 * 
 * sim_ril
 * 
 * n_chr   Number of chromosomes
 * n_mar   Number of markers on each chromosome (vector of length n_chr)
 * n_ril   Number of RILs to simulate
 * 
 * map     Vector of marker locations, of length sum(n_mar)
 *         First marker on each chromosome should be at 0.
 *
 * n_str   Number of parental strains (either 2, 4, or 8)
 *
 * m       Interference parameter (0 is no interference)
 * p       For Stahl model, proportion of chiasmata from the NI model
 *
 * include_x   Whether the last chromosome is the X chromosome
 *
 * random_cross  Indicates whether the order of the strains in the cross
 *               should be randomized.
 *
 * selfing If 1, use selfing; if 0, use sib mating
 *
 * cross   On output, the cross used for each line 
 *         (vector of length n_ril x n_str)
 *
 * ril     On output, the simulated data 
 *         (vector of length sum(n_mar) x n_ril)
 *
 * origgeno       Like ril, but with no missing data
 *
 * error_prob     Genotyping error probability (used nly with n_str==2)
 *
 * missing_prob   Rate of missing genotypes
 *
 * errors         Error indicators (n_mar x n_ril)
 *
 **********************************************************************/
void sim_ril(int n_chr, int *n_mar, int n_ril, double *map, 
	     int n_str, int m, double p, int include_x, 
	     int random_cross, int selfing, int *cross, int *ril,
	     int *origgeno, 
	     double error_prob, double missing_prob, int *errors)
{
  int i, j, k, ngen, tot_mar, curseg;
  struct individual par1, par2, kid1, kid2;
  int **Ril, **Cross, **Errors, **OrigGeno; 
  int maxwork, isX, flag, max_xo, *firstmarker;
  double **Map, maxlen, chrlen, *work;

 /* count total number of markers */
  for(i=0, tot_mar=0; i<n_chr; i++) 
    tot_mar += n_mar[i];

  reorg_geno(tot_mar, n_ril, ril, &Ril);
  reorg_geno(n_str, n_ril, cross, &Cross);
  reorg_geno(tot_mar, n_ril, errors, &Errors);
  reorg_geno(tot_mar, n_ril, origgeno, &OrigGeno);

  /* allocate space */
  Map = (double **)R_alloc(n_chr, sizeof(double *));
  Map[0] = map;
  for(i=1; i<n_chr; i++)
    Map[i] = Map[i-1] + n_mar[i-1];

  /* location of first marker */
  firstmarker = (int *)R_alloc(n_chr, sizeof(int));
  firstmarker[0] = 0;
  for(i=1; i<n_chr; i++) 
    firstmarker[i] = firstmarker[i-1] + n_mar[i-1];

  /* maximum chromosome length (in cM) */
  maxlen = Map[0][n_mar[0]-1];
  for(i=1; i<n_chr; i++)
    if(maxlen < Map[i][n_mar[i]-1])
      maxlen =  Map[i][n_mar[i]-1];

  /* allocate space for individuals */
  max_xo = (int)qpois(1e-10, maxlen/100.0, 0, 0)*6;
  if(!selfing) max_xo *= 5;
  allocate_individual(&par1, max_xo);
  allocate_individual(&par2, max_xo);
  allocate_individual(&kid1, max_xo);
  allocate_individual(&kid2, max_xo);
  maxwork = (int)qpois(1e-10, (m+1)*maxlen/50.0, 0, 0)*3;
  work = (double *)R_alloc(maxwork, sizeof(double));

  for(i=0; i<n_ril; i++) {

    /* set up cross */
    for(j=0; j<n_str; j++) Cross[i][j] = j+1;
    if(random_cross) int_permute(Cross[i], n_str);

    for(j=0; j<n_chr; j++) {
      isX = include_x && j==n_chr-1;

      chrlen = Map[j][n_mar[j]-1];

      par1.n_xo[0] = par1.n_xo[1] = par2.n_xo[0] = par2.n_xo[1] = 0;

      /* initial generations */
      if(n_str==2) {
	par1.allele[0][0] = par2.allele[0][0] = 1;
	par1.allele[1][0] = par2.allele[1][0] = 2;
      }
      else if(n_str==4) {
	par1.allele[0][0] = 1;
	par1.allele[1][0] = 2;
	par2.allele[0][0] = 3;
	par2.allele[1][0] = 4;
      }
      else { /* 8 strain case */
	par1.allele[0][0] = 1;
	par1.allele[1][0] = 2;
	par2.allele[0][0] = 3;
	par2.allele[1][0] = 4;

	docross(par1, par2, &kid1, chrlen, m, p, 0, 
	      &maxwork, &work);

	par1.allele[0][0] = 5;
	par1.allele[1][0] = 6;
	par2.allele[0][0] = 7;
	par2.allele[1][0] = 8;

	docross(par1, par2, &kid2, chrlen, m, p, isX,
	      &maxwork, &work);

	copy_individual(&kid1, &par1);
	copy_individual(&kid2, &par2);
      }

      /* start inbreeding */
      ngen=1;
      while(1) {
	R_CheckUserInterrupt(); /* check for ^C */

	docross(par1, par2, &kid1, chrlen, m, p, 0,
		&maxwork, &work);
	if(!selfing) 
	  docross(par1, par2, &kid2, chrlen, m, p, isX,
		  &maxwork, &work);

	/* are we done? */
	flag = 0;
	if(selfing) {
	  if(kid1.n_xo[0] == kid1.n_xo[1]) {
	    for(k=0; k<kid1.n_xo[0]; k++) {
	      if(kid1.allele[0][k] != kid1.allele[1][k] ||
		 fabs(kid1.xoloc[0][k] - kid1.xoloc[1][k]) > 1e-6) {
		flag = 1;
		break;
	      }
	    }
	    if(kid1.allele[0][kid1.n_xo[0]] != kid1.allele[1][kid1.n_xo[0]])
	      flag = 1;
	  }
	  else flag = 1;
	}
	else {
	  if(kid1.n_xo[0] == kid1.n_xo[1] && 
	     kid1.n_xo[0] == kid2.n_xo[0] && 
	     kid1.n_xo[0] == kid2.n_xo[1]) {
	    for(k=0; k<kid1.n_xo[0]; k++) {
	      if(kid1.allele[0][k] != kid1.allele[1][k] ||
		 kid1.allele[0][k] != kid2.allele[0][k] ||
		 kid1.allele[0][k] != kid2.allele[1][k] ||
		 fabs(kid1.xoloc[0][k] - kid1.xoloc[1][k]) > 1e-6 ||
		 fabs(kid1.xoloc[0][k] - kid2.xoloc[0][k]) > 1e-6 ||
		 fabs(kid1.xoloc[0][k] - kid2.xoloc[1][k]) > 1e-6) {
		flag = 1;
		break;
	      }
	    }
	    if(kid1.allele[0][kid1.n_xo[0]] != kid1.allele[1][kid1.n_xo[0]] ||
	       kid1.allele[0][kid1.n_xo[0]] != kid2.allele[0][kid1.n_xo[0]] ||
	       kid1.allele[0][kid1.n_xo[0]] != kid2.allele[1][kid1.n_xo[0]]) 
	      flag = 1;
	  }
	  else flag = 1;
	}

	if(!flag) break; /* done inbreeding */

	/* go to next generation */
	copy_individual(&kid1, &par1);
	if(selfing) copy_individual(&kid1, &par2);
	else copy_individual(&kid2, &par2);

      } /* end with inbreeding of this chromosome */

      /* fill in alleles */
      curseg = 0;
      for(k=0; k<n_mar[j]; k++) { /* loop over markers */
	while(curseg < kid1.n_xo[0] && Map[j][k] > kid1.xoloc[0][curseg]) 
	  curseg++;
	  
	OrigGeno[i][k+firstmarker[j]] = 
	  Ril[i][k+firstmarker[j]] = Cross[i][kid1.allele[0][curseg]-1];

	/* simulate missing ? */
	if(unif_rand() < missing_prob) {
	  Ril[i][k+firstmarker[j]] = 0;
	}
	else if(n_str == 2 && unif_rand() < error_prob) {
	  /* simulate error */
	  Ril[i][k+firstmarker[j]] = 3 - Ril[i][k+firstmarker[j]];
	  Errors[i][k+firstmarker[j]] = 1;
	}
      }

    } /* loop over chromosomes */

  } /* loop over lines */
}
Ejemplo n.º 9
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);
}
Ejemplo n.º 11
0
/**
 * GA with a single fitness function
 */
int evolve_both(int* first, int* second, int* winner, 
				int* loser, int* population) {
		int round = 0;
		float fitness_first, fitness_second;
		int first_bitflipped[GENOTYPE_LENGTH], 
			second_bitflipped[GENOTYPE_LENGTH];
		do {
				round++;
				// generate the complementary individuals
				bitflip(first, first_bitflipped);
				bitflip(second, second_bitflipped);

				// mark them as tested in the population
				population[hash(first)] = 1;
				population[hash(second)] = 1;

				// evaluate first and its complementary
				fitness_first = eval_fit(first, first_bitflipped);

				// evaluate second 
				fitness_second = eval_fit(second, second_bitflipped);

				// optimal solution?
				if ( fitness_first == 0.0 )
				{
						copy_individual(first, winner);
						copy_individual(second, loser);
						break;
				}
				if ( fitness_second == 0.0 )
				{
						copy_individual(second, winner);
						copy_individual(first, loser);
						break;
				}

				if ( fitness_first < fitness_second )
				{
						// first wins
						// mutate loser
						if ( mutate_1gene(second, population) < 0 )
						{
								// if no more mutations are possible
								copy_individual(first, winner);
								copy_individual(second, loser);
								break;
						}
				}
				else
				{
						// second wins
						// mutate loser
						if ( mutate_1gene(first, population) < 0 )
						{
								copy_individual(second, winner);
								copy_individual(first, loser);
								break;
						}
				}

		} while ( 1 );

		return round;
}