/*
* Data types
*/
+struct individual_s
+{
+ void *ptr;
+ int rating;
+};
+typedef struct individual_s individual_t;
+
struct population_s
{
pthread_mutex_t lock;
pi_free_f free;
pi_copy_f copy;
- void **individuals;
+ individual_t fittest;
+
+ individual_t *individuals;
size_t individuals_num;
};
pi_free_f f)
{
population_t *p;
+ size_t i;
p = (population_t *) malloc (sizeof (population_t));
if (p == NULL)
p->copy = copy;
p->free = f;
- p->individuals = (void **) malloc (32 * sizeof (void *));
+ p->fittest.ptr = NULL;
+ p->fittest.rating = -1;
+
+ p->individuals = malloc (32 * sizeof (p->individuals[0]));
if (p->individuals == NULL)
{
free (p);
return (NULL);
}
- memset (p->individuals, 0, 32 * sizeof (void *));
+ memset (p->individuals, 0, 32 * sizeof (p->individuals[0]));
p->individuals_num = 32;
+ for (i = 0; i < p->individuals_num; i++)
+ {
+ p->individuals[i].ptr = NULL;
+ p->individuals[i].rating = -1;
+ }
+
return (p);
} /* }}} population_t *population_create */
if (p == NULL)
return;
+ if (p->fittest.ptr != NULL)
+ p->free (p->fittest.ptr);
+ p->fittest.ptr = NULL;
+ p->fittest.rating = -1;
+
if (p->individuals_num > 0)
{
size_t i;
for (i = 0; i < p->individuals_num; i++)
{
- p->free (p->individuals[i]);
- p->individuals[i] = NULL;
+ if (p->individuals[i].ptr != NULL)
+ p->free (p->individuals[i].ptr);
+ p->individuals[i].ptr = NULL;
+ p->individuals[i].rating = -1;
}
free (p->individuals);
size_t population_size)
{
size_t i;
- void **temp;
+ individual_t *temp;
if (p == NULL)
return (-1);
for (i = population_size; i < p->individuals_num; i++)
{
- p->free (p->individuals[i]);
- p->individuals[i] = NULL;
+ p->free (p->individuals[i].ptr);
+ p->individuals[i].ptr = NULL;
+ p->individuals[i].rating = -1;
}
- temp = (void **) realloc (p->individuals, population_size * sizeof (void *));
+ temp = (individual_t *) realloc (p->individuals,
+ population_size * sizeof (p->individuals[0]));
if (temp == NULL)
{
pthread_mutex_unlock (&p->lock);
p->individuals = temp;
for (i = p->individuals_num; i < population_size; i++)
- p->individuals[i] = NULL;
+ {
+ p->individuals[i].ptr = NULL;
+ p->individuals[i].rating = -1;
+ }
p->individuals_num = population_size;
{
i = (size_t) (((double) p->individuals_num)
* (rand() / (RAND_MAX + 1.0)));
- if (p->individuals[i] == NULL)
+ if (p->individuals[i].ptr == NULL)
continue;
- ret = p->copy (p->individuals[i]);
+ ret = p->copy (p->individuals[i].ptr);
}
pthread_mutex_unlock (&p->lock);
void *population_get_fittest (population_t *p) /* {{{ */
{
void *ret = NULL;
- int best_rating;
- size_t i;
if (p == NULL)
return (NULL);
pthread_mutex_lock (&p->lock);
- best_rating = INT_MAX;
- for (i = 0; i < p->individuals_num; i++)
+ if (p->fittest.ptr == NULL)
{
- int rating;
-
- if (p->individuals[i] == NULL)
- continue;
-
- rating = p->rate (p->individuals[i]);
- if (rating < best_rating)
- {
- void *temp;
-
- temp = p->copy (p->individuals[i]);
- if (temp != NULL)
- {
- if (ret != NULL)
- p->free (ret);
- ret = temp;
- best_rating = rating;
- }
- }
+ pthread_mutex_unlock (&p->lock);
+ return (NULL);
}
+ ret = p->copy (p->fittest.ptr);
+
pthread_mutex_unlock (&p->lock);
return (ret);
pthread_mutex_lock (&p->lock);
+ /* Keep track of the all time best. */
+ if ((p->fittest.ptr == NULL) || (p->fittest.rating > pi_rating))
+ {
+ void *temp;
+
+ temp = p->copy (pi);
+ if (temp != NULL)
+ {
+ if (p->fittest.ptr != NULL)
+ p->free (p->fittest.ptr);
+ p->fittest.ptr = temp;
+ p->fittest.rating = pi_rating;
+ }
+ }
+
if (p->individuals_num <= 0)
{
pthread_mutex_unlock (&p->lock);
for (i = 0; i < num_tries; i++)
{
size_t j;
- int j_rating;
j = (size_t) (((double) p->individuals_num) * (rand() / (RAND_MAX + 1.0)));
- if (p->individuals[j] == NULL)
+ if (p->individuals[j].ptr == NULL)
{
- p->individuals[j] = pi;
+ p->individuals[j].ptr = pi;
+ p->individuals[j].rating = pi_rating;
pi = NULL;
break;
}
- j_rating = p->rate (p->individuals[j]);
-
- if (pi_rating < j_rating)
+ if (pi_rating < p->individuals[j].rating)
{
- void *temp;
+ void *temp0;
+ int temp1;
- temp = p->individuals[j];
- p->individuals[j] = pi;
- pi = temp;
+ temp0 = p->individuals[j].ptr;
+ p->individuals[j].ptr = pi;
+ pi = temp0;
- pi_rating = j_rating;
+ temp1 = p->individuals[j].rating;
+ p->individuals[j].rating = pi_rating;
+ pi_rating = temp1;
}
}