示例#1
0
int ga_deterministiccrowding(	population		*pop,
				const int		max_generations )
  {
  int		generation=0;		/* Current generation number. */
  int		*permutation, *ordered;	/* Arrays of entities. */
  entity	*mother, *father;	/* Current entities. */
  entity	*son, *daughter, *entity;	/* Current entities. */
  int		i;			/* Loop variable over entities. */
  double	dist1, dist2;		/* Genetic or phenomic distances. */
  int		rank;			/* Rank of entity in population. */

/* Checks. */
  if (!pop)
    die("NULL pointer to population structure passed.");
  if (!pop->dc_params)
    die("ga_population_set_deterministiccrowding_params(), or similar, must be used prior to ga_deterministiccrowding().");

  if (!pop->evaluate) die("Population's evaluation callback is undefined.");
  if (!pop->mutate) die("Population's mutation callback is undefined.");
  if (!pop->crossover) die("Population's crossover callback is undefined.");

  if (!pop->dc_params->compare) die("Population's comparison callback is undefined.");

  plog(LOG_VERBOSE, "The evolution by deterministic crowding has begun!");

  pop->generation = 0;

/*
 * Score the initial population members.
 */
  if (pop->size < pop->stable_size)
    gaul_population_fill(pop, pop->stable_size - pop->size);

  for (i=0; i<pop->size; i++)
    {
    if (pop->entity_iarray[i]->fitness == GA_MIN_FITNESS)
      pop->evaluate(pop, pop->entity_iarray[i]);
    }

  sort_population(pop);
  ga_genocide_by_fitness(pop, GA_MIN_FITNESS);


/*
 * Prepare arrays to store permutations.
 */
  permutation = s_malloc(sizeof(int)*pop->size);
  ordered = s_malloc(sizeof(int)*pop->size);
  for (i=0; i<pop->size;i++)
    ordered[i]=i;

  plog( LOG_VERBOSE,
        "Prior to the first generation, population has fitness scores between %f and %f",
        pop->entity_iarray[0]->fitness,
        pop->entity_iarray[pop->size-1]->fitness );

/*
 * Do all the generations:
 *
 * Stop when (a) max_generations reached, or
 *           (b) "pop->generation_hook" returns FALSE.
 */
  while ( (pop->generation_hook?pop->generation_hook(generation, pop):TRUE) &&
           generation<max_generations )
    {
    generation++;
    pop->generation = generation;
    pop->orig_size = pop->size;

    plog(LOG_DEBUG,
              "Population size is %d at start of generation %d",
              pop->orig_size, generation );

    sort_population(pop);

    random_int_permutation(pop->orig_size, ordered, permutation);

    for ( i=0; i<pop->orig_size; i++ )
      {
      mother = pop->entity_iarray[i];
      father = pop->entity_iarray[permutation[i]];

/*
 * Crossover step.
 */
      plog(LOG_VERBOSE, "Crossover between %d (rank %d fitness %f) and %d (rank %d fitness %f)",
           ga_get_entity_id(pop, mother),
           ga_get_entity_rank(pop, mother), mother->fitness,
           ga_get_entity_id(pop, father),
           ga_get_entity_rank(pop, father), father->fitness);

      son = ga_get_free_entity(pop);
      daughter = ga_get_free_entity(pop);
      pop->crossover(pop, mother, father, daughter, son);

/*
 * Mutation step.
 */
      if (random_boolean_prob(pop->mutation_ratio))
        {
        plog(LOG_VERBOSE, "Mutation of %d (rank %d)",
             ga_get_entity_id(pop, daughter),
             ga_get_entity_rank(pop, daughter) );

        entity = ga_get_free_entity(pop);
        pop->mutate(pop, daughter, entity);
        ga_entity_dereference(pop, daughter);
        daughter = entity;
        }

      if (random_boolean_prob(pop->mutation_ratio))
        {
        plog(LOG_VERBOSE, "Mutation of %d (rank %d)",
             ga_get_entity_id(pop, son),
             ga_get_entity_rank(pop, son) );

        entity = ga_get_free_entity(pop);
        pop->mutate(pop, son, entity);
        ga_entity_dereference(pop, son);
        son = entity;
        }

/*
 * Apply environmental adaptations, score entities, sort entities, etc.
 * FIXME: Currently no adaptation.
 */
      pop->evaluate(pop, daughter);
      pop->evaluate(pop, son);

/*
 * Evaluate similarities.
 */
      dist1 = pop->dc_params->compare(pop, mother, daughter) + pop->dc_params->compare(pop, father, son);
      dist2 = pop->dc_params->compare(pop, mother, son) + pop->dc_params->compare(pop, father, daughter);

/*
 * Determine which entities will survive, and kill the others.
 */
      if (dist1 < dist2)
        {
        rank = ga_get_entity_rank(pop, daughter);
        if (daughter->fitness < mother->fitness)
          {
          entity = pop->entity_iarray[i];
          pop->entity_iarray[i] = pop->entity_iarray[rank];
          pop->entity_iarray[rank] = entity;
          }
        ga_entity_dereference_by_rank(pop, rank);

        rank = ga_get_entity_rank(pop, son);
        if (son->fitness < father->fitness)
          {
          entity = pop->entity_iarray[permutation[i]];
          pop->entity_iarray[permutation[i]] = pop->entity_iarray[rank];
          pop->entity_iarray[rank] = entity;
          }
        ga_entity_dereference_by_rank(pop, rank);
        }
      else
        {
        rank = ga_get_entity_rank(pop, son);
        if (son->fitness < mother->fitness)
          {
          entity = pop->entity_iarray[i];
          pop->entity_iarray[i] = pop->entity_iarray[rank];
          pop->entity_iarray[rank] = entity;
          }
        ga_entity_dereference_by_rank(pop, rank);

        rank = ga_get_entity_rank(pop, daughter);
        if (daughter->fitness < father->fitness)
          {
          entity = pop->entity_iarray[permutation[i]];
          pop->entity_iarray[permutation[i]] = pop->entity_iarray[rank];
          pop->entity_iarray[rank] = entity;
          }
        ga_entity_dereference_by_rank(pop, rank);
        }
      }

/*
 * Use callback.
 */
    plog(LOG_VERBOSE,
          "After generation %d, population has fitness scores between %f and %f",
          generation,
          pop->entity_iarray[0]->fitness,
          pop->entity_iarray[pop->size-1]->fitness );

    }	/* Generation loop. */

/*
 * Ensure final ordering of population is correct.
 */
  sort_population(pop);

  return generation;
  }
示例#2
0
文件: ga_sa.c 项目: versionzero/gaul
GAULFUNC int ga_sa(	population		*pop,
		entity			*initial,
		const int		max_iterations )
  {
  int		iteration=0;		/* Current iteration number. */
  entity	*putative;		/* Current solution. */
  entity	*best;			/* Current solution. */
  entity	*tmp;			/* Used to swap working solutions. */

/* Checks. */
  if (!pop) die("NULL pointer to population structure passed.");
  if (!pop->evaluate) die("Population's evaluation callback is undefined.");
  if (!pop->mutate) die("Population's mutation callback is undefined.");
  if (!pop->sa_params) die("ga_population_set_sa_params(), or similar, must be used prior to ga_sa().");

/* Prepare working entities. */
  putative = ga_get_free_entity(pop);
  best = ga_get_free_entity(pop);

/* Do we need to generate a random starting solution? */
  if (!initial)
    {
    plog(LOG_VERBOSE, "Will perform simulated annealling with random starting solution.");

    initial = ga_get_free_entity(pop);
    ga_entity_seed(pop, best);
    }
  else
    {   
    plog(LOG_VERBOSE, "Will perform simulated annealling with specified starting solution.");
    ga_entity_copy(pop, best, initial);
    }

/*
 * Ensure that initial solution is scored.
 */
  if (best->fitness==GA_MIN_FITNESS) pop->evaluate(pop, best);

  plog( LOG_VERBOSE,
        "Prior to the first iteration, the current solution has fitness score of %f",
        best->fitness );

/*
 * Do all the iterations:
 *
 * Stop when (a) max_iterations reached, or
 *           (b) "pop->iteration_hook" returns FALSE.
 */
  pop->sa_params->temperature = pop->sa_params->initial_temp;

  while ( (pop->iteration_hook?pop->iteration_hook(iteration, best):TRUE) &&
           iteration<max_iterations )
    {
    iteration++;

    if (pop->sa_params->temp_freq == -1)
      {
      pop->sa_params->temperature = pop->sa_params->initial_temp
                                  + ((double)iteration/max_iterations)
                                  * (pop->sa_params->final_temp-pop->sa_params->initial_temp);
      }
    else
      {
      if (    pop->sa_params->temperature > pop->sa_params->final_temp
           && iteration%pop->sa_params->temp_freq == 0 )
        {
        pop->sa_params->temperature -= pop->sa_params->temp_step;
        }
      }

/*
 * Generate and score a new solution.
 */
  pop->mutate(pop, best, putative);
  pop->evaluate(pop, putative);

/*
 * Use the acceptance criterion to decide whether this new solution should
 * be selected or discarded.
 */
  if ( pop->sa_params->sa_accept(pop, best, putative) )
    {
    tmp = best;
    best = putative;
    putative = tmp;
    }

/*
 * Save the current best solution in the initial entity, if this
 * is now the best found so far.
 */
  if ( initial->fitness<best->fitness )
    {
    ga_entity_blank(pop, initial);
    ga_entity_copy(pop, initial, best);
    }

/*
 * Use the iteration callback.
 */
    plog( LOG_VERBOSE,
          "After iteration %d, the current solution has fitness score of %f",
          iteration,
          best->fitness );

    }	/* Iteration loop. */

/*
 * Cleanup.
 */
  ga_entity_dereference(pop, best);
  ga_entity_dereference(pop, putative);

  return iteration;
  }
示例#3
0
GAULFUNC int ga_random_search(	population		*pop,
			entity			*best,
			const int		max_iterations )
  {
  int		iteration=0;		/* Current iteration number. */
  entity	*putative;		/* Current solution. */
  entity	*tmp;			/* Used to swap entities. */

/* Checks. */
  if (!pop) die("NULL pointer to population structure passed.");
  if (pop->size < 1) die("Population is empty.");
  if (!pop->evaluate) die("Population's evaluation callback is undefined.");
  if (!pop->seed) die("Population's seed callback is undefined.");

/* Prepare working entity. */
  putative = ga_get_free_entity(pop);

/* Do we need to generate a random starting solution? */
  if (!best)
    {
    plog(LOG_VERBOSE, "Will perform random search with random starting solution.");

    best = ga_get_free_entity(pop);
    ga_entity_seed(pop, best);
    }
  else
    {   
    plog(LOG_VERBOSE, "Will perform random search with specified starting solution.");
    }

/*
 * Ensure that initial solution is scored.
 */
  if (best->fitness==GA_MIN_FITNESS) pop->evaluate(pop, best);

  plog( LOG_VERBOSE,
        "Prior to the first iteration, the current solution has fitness score of %f",
        best->fitness );

/*
 * Do all the iterations:
 *
 * Stop when (a) max_iterations reached, or
 *           (b) "pop->iteration_hook" returns FALSE.
 */
  while ( (pop->iteration_hook?pop->iteration_hook(iteration, best):TRUE) &&
           iteration<max_iterations )
    {
    iteration++;

/*
 * Generate and score a new solution.
 */
    ga_entity_blank(pop, putative);
    pop->seed(pop, putative);
    pop->evaluate(pop, putative);

/*
 * Decide whether this new solution should be selected or discarded based
 * on the relative fitnesses.
 */
  if ( putative->fitness > best->fitness )
    {
    tmp = best;
    best = putative;
    putative = tmp;
    }

/*
 * Use the iteration callback.
 */
    plog( LOG_VERBOSE,
          "After iteration %d, the current solution has fitness score of %f",
          iteration,
          best->fitness );

    }	/* Iteration loop. */

/*
 * Cleanup.
 */
  ga_entity_dereference(pop, putative);

  return iteration;
  }
示例#4
0
GAULFUNC int ga_search(	population		*pop,
		entity			*best)
  {
  int		iteration=0;		/* Current iteration number. */
  entity	*putative;		/* Current solution. */
  entity	*tmp;			/* Used to swap entities. */
  int		enumeration=0;		/* Enumeration index. */
  boolean	finished=FALSE;		/* Whether search is complete. */

/* Checks. */
  if (!pop) die("NULL pointer to population structure passed.");
  if (!pop->evaluate) die("Population's evaluation callback is undefined.");
  if (!pop->search_params) die("ga_population_set_search_params(), or similar, must be used prior to ga_search().");
  if (!pop->search_params->scan_chromosome) die("Population's chromosome scan callback is undefined.");

/* Prepare working entity. */
  putative = ga_get_free_entity(pop);

  plog(LOG_VERBOSE, "Will perform systematic search.");

/* Do we need to allocate starting solution? */
  if (!best)
    {
    best = ga_get_free_entity(pop);
    ga_entity_seed(pop, best);
    }

/*
 * Ensure that initial solution is scored.
 */
  if (best->fitness==GA_MIN_FITNESS) pop->evaluate(pop, best);

/*
 * Prepare internal data for the enumeration algorithm.
 */
  pop->search_params->chromosome_state = 0;
  pop->search_params->allele_state = 0;

/*
 * Do all the iterations:
 *
 * Stop when (a) All enumerations performed or
 *           (b) "pop->iteration_hook" returns FALSE.
 */
  while ( (pop->iteration_hook?pop->iteration_hook(iteration, best):TRUE) &&
           finished == FALSE )
    {
    iteration++;

/*
 * Generate and score a new solution.
 */
    ga_entity_blank(pop, putative);
    finished = pop->search_params->scan_chromosome(pop, putative, enumeration);
    pop->evaluate(pop, putative);

/*
 * Decide whether this new solution should be selected or discarded based
 * on the relative fitnesses.
 */
  if ( putative->fitness > best->fitness )
    {
    tmp = best;
    best = putative;
    putative = tmp;
    }

/*
 * Use the iteration callback.
 */
    plog( LOG_VERBOSE,
          "After iteration %d, the current solution has fitness score of %f",
          iteration,
          best->fitness );

    }	/* Iteration loop. */

/*
 * Cleanup.
 */
  ga_entity_dereference(pop, putative);

  return iteration;
  }
示例#5
0
文件: ga_tabu.c 项目: dunghand/msrds
GAULFUNC int ga_tabu(	population		*pop,
		entity			*initial,
		const int		max_iterations )
  {
  int		iteration=0;		/* Current iteration number. */
  int		i, j;			/* Index into putative solution array. */
  entity	*best;			/* Current best solution. */
  entity	**putative;		/* Current working solutions. */
  entity	*tmp;			/* Used to swap working solutions. */
  entity	**tabu_list;		/* Tabu list. */
  int		tabu_list_pos=0;	/* Index into the tabu list. */

/* Checks. */
  if (!pop) die("NULL pointer to population structure passed.");
  if (!pop->evaluate) die("Population's evaluation callback is undefined.");
  if (!pop->mutate) die("Population's mutation callback is undefined.");
  if (!pop->rank) die("Population's ranking callback is undefined.");
  if (!pop->tabu_params) die("ga_population_set_tabu_params(), or similar, must be used prior to ga_tabu().");
  if (!pop->tabu_params->tabu_accept) die("Population's tabu acceptance callback is undefined.");

/* Prepare working entities. */
  best = ga_get_free_entity(pop);	/* The best solution so far. */
  if ( !(putative = s_malloc(sizeof(entity *)*pop->tabu_params->search_count)) )
    die("Unable to allocate memory");

  for (i=0; i<pop->tabu_params->search_count; i++)
    {
    putative[i] = ga_get_free_entity(pop);    /* The 'working' solutions. */
    }

/* Allocate and clear an array for the tabu list. */
  if ( !(tabu_list = s_malloc(sizeof(vpointer)*pop->tabu_params->list_length)) )
    die("Unable to allocate memory");

  for (i=0; i<pop->tabu_params->list_length; i++)
    {
    tabu_list[i] = NULL;
    }

/* Do we need to generate a random starting solution? */
  if (!initial)
    {
    plog(LOG_VERBOSE, "Will perform tabu-search with random starting solution.");

    initial = ga_get_free_entity(pop);
    ga_entity_seed(pop, best);
    }
  else
    {   
    plog(LOG_VERBOSE, "Will perform tabu-search with specified starting solution.");
    ga_entity_copy(pop, best, initial);
    }

/*
 * Ensure that initial solution is scored.
 */
  if (best->fitness==GA_MIN_FITNESS) pop->evaluate(pop, best);

  plog( LOG_VERBOSE,
        "Prior to the first iteration, the current solution has fitness score of %f",
        best->fitness );

/*
 * Do all the iterations:
 *
 * Stop when (a) max_iterations reached, or
 *           (b) "pop->iteration_hook" returns FALSE.
 */
  while ( (pop->iteration_hook?pop->iteration_hook(iteration, best):TRUE) &&
           iteration<max_iterations )
    {
    iteration++;

/*
 * Generate and score new solutions.
 */
    for (i=0; i<pop->tabu_params->search_count; i++)
      {
      pop->mutate(pop, best, putative[i]);
      pop->evaluate(pop, putative[i]);
      }

/*
 * Sort new solutions (putative[0] will have highest rank).
 * We assume that there are only a small(ish) number of
 * solutions and, therefore, a simple bubble sort is adequate.
 */
    for (i=1; i<pop->tabu_params->search_count; i++)
      {
      for (j=pop->tabu_params->search_count-1; j>=i; j--)
        {
        if ( pop->rank(pop, putative[j], pop, putative[j-1]) > 0 )
          {	/* Perform a swap. */
          tmp = putative[j];
          putative[j] = putative[j-1];
          putative[j-1] = tmp;
          }
        }
      }

/*
 * Save best solution if it is an improvement, otherwise
 * select the best non-tabu solution (if any).
 * If appropriate, update the tabu list.
 */
  if ( pop->rank(pop, putative[0], pop, best) > 0 )
    {
    tmp = best;
    best = putative[0];
    putative[0] = tmp;
    if (tabu_list[tabu_list_pos] == NULL)
      {
      tabu_list[tabu_list_pos] = ga_entity_clone(pop, best);
      }
    else
      {
      ga_entity_blank(pop, tabu_list[tabu_list_pos]);
      ga_entity_copy(pop, tabu_list[tabu_list_pos], best);
      }
    tabu_list_pos++;
    if (tabu_list_pos >= pop->tabu_params->list_length)
      tabu_list_pos=0;
    }
  else
    {
    if ( -1 < (j = gaul_check_tabu_list(pop, putative, tabu_list)) )
      {
      tmp = best;
      best = putative[j];
      putative[j] = tmp;
      if (tabu_list[tabu_list_pos] == NULL)
        {
        tabu_list[tabu_list_pos] = ga_entity_clone(pop, best);
        }
      else
        {
        ga_entity_blank(pop, tabu_list[tabu_list_pos]);
        ga_entity_copy(pop, tabu_list[tabu_list_pos], best);
        }
      tabu_list_pos++;
      if (tabu_list_pos >= pop->tabu_params->list_length)
        tabu_list_pos=0;
      }
    }

/*
 * Save the current best solution in the initial entity, if this
 * is now the best found so far.
 */
  if ( pop->rank(pop, best, pop, initial) > 0 )
    {
    ga_entity_blank(pop, initial);
    ga_entity_copy(pop, initial, best);
    }

/*
 * Use the iteration callback.
 */
    plog( LOG_VERBOSE,
          "After iteration %d, the current solution has fitness score of %f",
          iteration,
          best->fitness );

    }	/* Iteration loop. */

/*
 * Cleanup.
 */
  ga_entity_dereference(pop, best);

  for (i=0; i<pop->tabu_params->search_count; i++)
    {
    ga_entity_dereference(pop, putative[i]);
    }

  for (i=0; i<pop->tabu_params->list_length; i++)
    {
    if (tabu_list[i] != NULL)
      ga_entity_dereference(pop, tabu_list[i]);
    }

  s_free(putative);
  s_free(tabu_list);

  return iteration;
  }
示例#6
0
GAULFUNC entity *ga_allele_search(	population	*pop,
				const int	chromosomeid,
				const int	point,
				const int 	min_val,
				const int 	max_val,
				entity		*initial )
  {
  int		val;			/* Current value for point. */
  entity	*current, *best;	/* The solutions. */

/* Checks. */
/* FIXME: More checks needed. */
  if ( !pop ) die("Null pointer to population structure passed.");

  current = ga_get_free_entity(pop);	/* The 'working' solution. */
  best = ga_get_free_entity(pop);	/* The best solution so far. */

  plog(LOG_WARNING, "ga_allele_search() is a deprecated function!");

/* Do we need to generate a random solution? */
  if (initial==NULL)
    {
    plog(LOG_VERBOSE, "Will perform systematic allele search with random starting solution.");

    pop->seed(pop, best);
    }
  else
    {
    plog(LOG_VERBOSE, "Will perform systematic allele search.");

    ga_entity_copy(pop, best, initial);
    }

/*
 * Copy best solution over current solution.
 */
  ga_entity_copy(pop, current, best);
  best->fitness=GA_MIN_FITNESS;

/*
 * Loop over the range of legal values.
 */
  for (val = min_val; val < max_val; val++)
    {
    ((int *)current->chromosome[chromosomeid])[point] = val;
    ga_entity_clear_data(pop, current, chromosomeid);

    pop->evaluate(pop, current);

/*
 * Should we keep this solution?
 */
    if ( best->fitness < current->fitness )
      { /* Copy this solution best solution. */
      ga_entity_blank(pop, best);
      ga_entity_copy(pop, best, current);
      }
    else
      { /* Copy best solution over current solution. */
      ga_entity_blank(pop, current);
      ga_entity_copy(pop, current, best);
      }

    }

  plog(LOG_VERBOSE,
            "After complete search the best solution has fitness score of %f",
            best->fitness );

/*
 * Current no longer needed.  It is upto the caller to dereference the
 * optimum solution found.
 */
  ga_entity_dereference(pop, current);

  return best;
  }
示例#7
0
文件: ga_gradient.c 项目: aaasz/SHP
int ga_steepestascent_double(	population	*pop,
			entity		*current,
			const int	max_iterations )
  {
  int		iteration=0;		/* Current iteration number. */
  int		i;			/* Index into arrays. */
  double	*current_g;		/* Current iteration gradient array. */
  entity	*putative;		/* New solution. */
  entity	*tmpentity;		/* Used to swap working solutions. */
  double	step_size;		/* Current step size. */
  double	grms;			/* Current RMS gradient. */
  boolean	force_terminate=FALSE;	/* Force optimisation to terminate. */

/*
 * Checks.
 */
  if (!pop) die("NULL pointer to population structure passed.");
  if (!pop->evaluate) die("Population's evaluation callback is undefined.");
  if (!pop->gradient_params) die("ga_population_set_gradient_params(), or similar, must be used prior to ga_gradient().");
  if (!pop->gradient_params->gradient) die("Population's first derivatives callback is undefined.");

/* 
 * Prepare working entity and gradient array.
 */
  current_g = s_malloc(sizeof(double)*pop->len_chromosomes);

  putative = ga_get_free_entity(pop);

/* Do we need to generate a random starting solution? */
  if (current==NULL)
    {
    plog(LOG_VERBOSE, "Will perform gradient search with random starting solution.");

    current = ga_get_free_entity(pop);
    ga_entity_seed(pop, current);
    }
  else
    {   
    plog(LOG_VERBOSE, "Will perform gradient search with specified starting solution.");
    }

/*
 * Get initial fitness and derivatives.
 */
  pop->evaluate(pop, current);

  grms = pop->gradient_params->gradient(pop, current, (double *)current->chromosome[0], current_g);

  plog( LOG_VERBOSE,
        "Prior to the first iteration, the current solution has fitness score of %f and a RMS gradient of %f",
         current->fitness, grms );

/*
 * Adjust step size based on gradient.
 * This scales the step size according to the initial gradient so that the
 * calculation doesn't blow-up completely.
 */
/*  step_size=(pop->len_chromosomes*pop->gradient_params->step_size)/grms;*/
  step_size=pop->gradient_params->step_size;

/*
 * Do all the iterations:
 *
 * Stop when (a) max_iterations reached, or
 *           (b) "pop->iteration_hook" returns FALSE.
 * The iteration hook could evaluate the RMS gradient, or the maximum component
 * of the gradient, or any other termination criteria that may be desirable.
 */
  while ( force_terminate==FALSE &&
          (pop->iteration_hook?pop->iteration_hook(iteration, current):TRUE) &&
          iteration<max_iterations )
    {
    iteration++;

    for( i=0; i<pop->len_chromosomes; i++ )
      ((double *)putative->chromosome[0])[i]=((double *)current->chromosome[0])[i]+step_size*current_g[i];

    pop->evaluate(pop, putative);

#if GA_DEBUG>2
    printf("DEBUG: current_d = %f %f %f %f\n", current_d[0], current_d[1], current_d[2], current_d[3]);
    printf("DEBUG: current_g = %f %f %f %f grms = %f\n", current_g[0], current_g[1], current_g[2], current_g[3], grms);
    printf("DEBUG: putative_d = %f %f %f %f fitness = %f\n", putative_d[0], putative_d[1], putative_d[2], putative_d[3], putative->fitness);
#endif

    if ( current->fitness > putative->fitness )
      {	/* New solution is worse. */

      do
        {
        step_size *= pop->gradient_params->alpha;
        /*printf("DEBUG: step_size = %e\n", step_size);*/

        for( i=0; i<pop->len_chromosomes; i++ )
          ((double *)putative->chromosome[0])[i]=((double *)current->chromosome[0])[i]+step_size*current_g[i];

        pop->evaluate(pop, putative);
        } while( current->fitness > putative->fitness && step_size > ApproxZero);

      if (step_size <= ApproxZero && grms <= ApproxZero) force_terminate=TRUE;
      }
    else 
      {	/* New solution is an improvement. */
      step_size *= pop->gradient_params->beta;
#if GA_DEBUG>2
      printf("DEBUG: step_size = %e\n", step_size);
#endif
      }

/* Store improved solution. */
    tmpentity = current;
    current = putative;
    putative = tmpentity;

    grms = pop->gradient_params->gradient(pop, current, (double *)current->chromosome[0], current_g);

/*
 * Use the iteration callback.
 */
    plog( LOG_VERBOSE,
          "After iteration %d, the current solution has fitness score of %f and RMS gradient of %f (step_size = %f)",
          iteration, current->fitness, grms, step_size );

    }	/* Iteration loop. */

/*
 * Cleanup.
 */
  ga_entity_dereference(pop, putative);

  return iteration;
  }
示例#8
0
GAULFUNC int ga_random_ascent_hillclimbing(	population		*pop,
					entity			*best,
					const int		max_iterations )
  {
  int		iteration=0;		/* Current iteration number. */
  entity	*putative;		/* Current solution. */
  entity	*tmp;			/* Used to swap working solutions. */
  int		chromo_id;		/* Chromosome number. */
  int		allele_id;		/* Allele number. */

/* Checks. */
  if (!pop) die("NULL pointer to population structure passed.");
  if (!pop->evaluate) die("Population's evaluation callback is undefined.");
  if (!pop->climbing_params)
    die("ga_population_set_hillclimbing_params(), or similar, must be used prior to ga_random_ascent_hillclimbing().");
  if (!pop->climbing_params->mutate_allele)
    die("Population's allele mutation callback is undefined.");

/* Prepare working entity. */
  putative = ga_get_free_entity(pop);

/* Do we need to generate a random starting solution? */
  if (!best)
    {
    plog(LOG_VERBOSE, "Will perform hill climbing with random starting solution.");

    best = ga_get_free_entity(pop);
    ga_entity_seed(pop, best);
    }
  else
    {   
    plog(LOG_VERBOSE, "Will perform hill climbing with specified starting solution.");
    }

/*
 * Ensure that initial solution is scored.
 */
  if (best->fitness==GA_MIN_FITNESS) pop->evaluate(pop, best);

  plog( LOG_VERBOSE,
        "Prior to the first iteration, the current solution has fitness score of %f",
        best->fitness );

/*
 * Do all the iterations:
 *
 * Stop when (a) max_iterations reached, or
 *           (b) "pop->iteration_hook" returns FALSE.
 */
  while ( (pop->iteration_hook?pop->iteration_hook(iteration, best):TRUE) &&
           iteration<max_iterations )
    {
    iteration++;

/*
 * Generate and score a new solution.
 */
    chromo_id = random_int(pop->num_chromosomes);
    allele_id = random_int(pop->len_chromosomes);
    pop->climbing_params->mutate_allele(pop, best, putative, chromo_id, allele_id);
    pop->mutate(pop, best, putative);
    pop->evaluate(pop, putative);

/*
 * Decide whether this new solution should be selected or discarded based
 * on the relative fitnesses.
 */
  if ( putative->fitness > best->fitness )
    {
    tmp = best;
    best = putative;
    putative = tmp;
    }

/*
 * Use the iteration callback.
 */
    plog( LOG_VERBOSE,
          "After iteration %d, the current solution has fitness score of %f",
          iteration,
          best->fitness );

    }	/* Iteration loop. */

/*
 * Cleanup.
 */
  ga_entity_dereference(pop, putative);

  return iteration;
  }