Exemple #1
0
GAULFUNC boolean ga_sa_boltzmann_acceptance( population	*pop,
				entity		*original,
				entity		*putative )
  {

  return ( original->fitness < putative->fitness ||
           random_boolean_prob(exp((putative->fitness-original->fitness)
           /(GA_BOLTZMANN_FACTOR*pop->sa_params->temperature))) );
  }
Exemple #2
0
void pingpong_mutate(population *pop, entity *mother, entity *son)
  {

  /* Checks. */
  if (!mother || !son) die("Null pointer to entity structure passed");

  if (random_boolean_prob(0.5))
    pingpong_mutate_swap(pop, mother, son);
  else
    pingpong_mutate_shift(pop, mother, son);

  return;
  }
Exemple #3
0
boolean wildfire_seed(population *pop, entity *adam)
  {
  int		i, j, k;	/* Map square. */

  if (random_boolean())
    {
    for(i=0; i<WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION; i++)
      {
      ((int *)adam->chromosome[0])[i] = random_boolean_prob((double)WILDFIRE_CISTERNS/
                 ((double)WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION));
      }
    }
  else
    {
    for(i=0; i<WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION; i++)
      {
      ((int *)adam->chromosome[0])[i] = 0;
      }

    /* Deliberately places slightly fewer cisterns than allowed. */
    i = random_int(WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION);
    j = random_int(WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION);
    k = WILDFIRE_CISTERNS;
    while (k>0)
      {
      i = (i+j)%(WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION);
      if (((int *)adam->chromosome[0])[i] == 1)
        {
        j = random_int(WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION);
        }
      else
        {
        ((int *)adam->chromosome[0])[i] = 1;
        }
      k--;
      }
    }

  return TRUE;
  }
Exemple #4
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;
  }
Exemple #5
0
boolean random_boolean_prob_wrapper(double *prob)
  {
  return random_boolean_prob(*prob);
  }
Exemple #6
0
double wildfire_simulation(int map[WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION], boolean show)
  {
  int		time;		/* Simulation time. */
  int		burning[WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION];	/* Map. */
  int		crews[WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION];	/* Map. */
  int		num_burnt=0;	/* Number of burnt squares. */
  int		i, j, k;	/* Loop variables. */
  int		p;		/* Selected map square. */
  int		dir;		/* Wind direction. */

  /* Start with no burnt squares. */
  for(p=0; p<WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION; p++)
    burning[p] = 0;

  /* Random initial wind direction. */
  dir = random_int(4);

  /* Perform simulation. */
  for(time=0; time<WILDFIRE_TIME; time++)
    {
    /* Set fire to random squares. */
    for(i=0; i<WILDFIRE_FLASHPOINTS; i++)
      {
      p = random_int(WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION);
      if (map[p] == 0 && burning[p] == 0) burning[p]=1;
      }

    /* Apply the wind direction changing. */
    if (WILDFIRE_PREDICTABLE_WIND == TRUE)
      {
      if (dir==3)
        dir=0;
      else
        dir++;
      }
    else if ( random_boolean_prob(WILDFIRE_WIND_CHANGE_PROB) )
      {
      dir = random_int(4);
      }

    /* Fire crews try their best. */
    /* Look for fires that can spread most easily, and extinguish them. */
    /* FIXME: Implement firecrews to take account of predictable winds. */
    /* Currently very simple: Extinguish fires that will spread the most
       during this day. */
    /* Firstly, assess the fires. */
    switch (dir)
      {
      case 0:
        /* North */
        for(p=0; p<WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION; p++)
          {
          if (burning[p] > 0 && burning[p] < 2)
            {
            crews[p]=1;
            while( crews[p]<WILDFIRE_WIND_SPEED &&
                   (j=p-crews[p]*WILDFIRE_X_DIMENSION)>0 &&
                   map[j] == 0 &&
                   burning[j] == 0 )
              {
              crews[p]++;
              }
            }
          else
            {
            crews[p]=0;
            }
          }
        break;
      case 1:
        /* East */
        for(p=WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION-1; p>=0; p--)
          {
          if (burning[p] > 0 && burning[p] < 2)
            {
            crews[p]=1;
            while( crews[p]<WILDFIRE_WIND_SPEED &&
                   (j=p+crews[p])%WILDFIRE_X_DIMENSION<(WILDFIRE_X_DIMENSION-1) &&
                   map[j] == 0 &&
                   burning[j] == 0 )
              {
              crews[p]++;
              }
            }
          else
            {
            crews[p]=0;
            }
          }
        break;
      case 2:
        /* South */
        for(p=WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION-1; p>=0; p--)
          {
          if (burning[p] > 0 && burning[p] < 2)
            {
            crews[p]=1;
            while( crews[p]<WILDFIRE_WIND_SPEED &&
                   (j=p+crews[p]*WILDFIRE_X_DIMENSION)<(WILDFIRE_Y_DIMENSION-1) &&
                   map[j] == 0 &&
                   burning[j] == 0 )
              {
              crews[p]++;
              }
            }
          else
            {
            crews[p]=0;
            }
          }
        break;
      case 3:
        /* West */
        for(p=0; p<WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION; p++)
          {
          if (burning[p] > 0 && burning[p] < 2)
            {
            crews[p]=1;
            while( crews[p]<WILDFIRE_WIND_SPEED &&
                   (j=p-crews[p])%WILDFIRE_X_DIMENSION>0 &&
                   map[j] == 0 &&
                   burning[j] == 0 )
              {
              crews[p]++;
              }
            }
          else
            {
            crews[p]=0;
            }
          }
        break;
      }

    /* Assign the firecrews. */
    k = WILDFIRE_CREWS;
    j = WILDFIRE_WIND_SPEED;
    while (j>0 && k>0)
      {
      for(p=0; p<WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION && k>0; p++)
        {
        if (crews[p]==j)
          {
          crews[p]=-1;
          burning[p]=0;
          k--;
          }
        }
      j--;
      }

    /* Age fires. */
    for(p=0; p<WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION; p++)
      {
      if (burning[p] > 0 ) burning[p]++;
      }

    for (k=0; k<WILDFIRE_WIND_SPEED; k++)
      {
      /* Spread fires. */
      switch (dir)
        {
        case 0:
          /* North */
          for(p=0; p<WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION; p++)
            {
            if (burning[p] > 0 && burning[p] < 3)
              {
              if (p>WILDFIRE_X_DIMENSION)
                if ( map[p-WILDFIRE_X_DIMENSION] == 0 &&
                     burning[p-WILDFIRE_X_DIMENSION] == 0 &&
                     crews[p-WILDFIRE_X_DIMENSION] != -1 )
                  burning[p-WILDFIRE_X_DIMENSION]=1;
              }
            }
          break;
        case 1:
          /* East */
          for(p=WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION-1; p>=0; p--)
            {
            if (burning[p] > 0 && burning[p] < 3)
              {
              if (p%WILDFIRE_X_DIMENSION<(WILDFIRE_X_DIMENSION-1))
                if ( map[p+1] == 0 &&
                     burning[p+1] == 0 &&
                     crews[p+1] != -1 )
                  burning[p+1]=1;
              }
            }
          break;
        case 2:
          /* South */
          for(p=WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION-1; p>=0; p--)
            {
            if (burning[p] > 0 && burning[p] < 3)
              {
              if (p<WILDFIRE_X_DIMENSION*(WILDFIRE_Y_DIMENSION-1))
                if ( map[p+WILDFIRE_X_DIMENSION] == 0 &&
                     burning[p+WILDFIRE_X_DIMENSION] == 0 &&
                     crews[p+WILDFIRE_X_DIMENSION] != -1 )
                  burning[p+WILDFIRE_X_DIMENSION]=1;
              }
            }
          break;
        case 3:
          /* West */
          for(p=0; p<WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION; p++)
            {
            if (burning[p] > 0 && burning[p] < 3)
              {
              if (p%WILDFIRE_X_DIMENSION>0)
                if ( map[p-1] == 0 &&
                     burning[p-1] == 0 &&
                     crews[p-1] != -1 )
                  burning[p-1]=1;
              }
            }
          break;
        }
      }
    }

  /* Count number of burnt squares. */
  for(i=0; i<WILDFIRE_X_DIMENSION*WILDFIRE_Y_DIMENSION; i++)
    if (burning[i]!=0) num_burnt++;

  if (show)
    {
    printf("Map after simulation is:\n");
    for (i=0; i<WILDFIRE_Y_DIMENSION; i++)
      {
      for (k=0; k<WILDFIRE_X_DIMENSION; k++)
        {
        printf( "%s ", map[i*WILDFIRE_X_DIMENSION+k]?"o":
                       ((burning[i*WILDFIRE_X_DIMENSION+k]==0)?
                       ((crews[i*WILDFIRE_X_DIMENSION+k]==-1)?"*":"."):"x") );
        }
      printf("\n");
      }
    }
  
  return num_burnt;
  }