Esempio n. 1
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;
  }
Esempio n. 2
0
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;
  }
Esempio n. 3
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;
  }
Esempio n. 4
0
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;
  }
Esempio n. 5
0
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;
  }
Esempio n. 6
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;
  }