예제 #1
0
파일: ga_utility.c 프로젝트: dunghand/msrds
GAULFUNC void ga_entity_dump(population *pop, entity *john)
  {
  printf( "Entity id %d rank %d\n",
          ga_get_entity_id(pop, john),
          ga_get_entity_rank(pop, john) );
  printf( "Fitness %f\n", john->fitness );
  printf( "data <%s> data0 <%s> chromo <%s> chromo0 <%s>\n",
          john->data?"defined":"undefined",
          john->data!=NULL&&((SLList *)john->data)->data!=NULL?"defined":"undefined",
          john->chromosome?"defined":"undefined",
          john->chromosome!=NULL&&john->chromosome[0]!=NULL?"defined":"undefined" );

  return;
  }
예제 #2
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;
  }