src/libpopulation.c: Changed insert code for more variance.
authorFlorian Forster <octo@leeloo.home.verplant.org>
Sat, 12 Jul 2008 09:37:51 +0000 (11:37 +0200)
committerFlorian Forster <octo@leeloo.home.verplant.org>
Sat, 12 Jul 2008 09:37:51 +0000 (11:37 +0200)
The new code gives every individual a chance to get in the population,
and even the best known solution may be removed from the population.
That's why the best ever solution is stored separately, so it is not
"lost".

Hopefully this code creates some more diversion.

src/libpopulation.c

index c5d3c4e..aa5b9dc 100644 (file)
@@ -511,11 +511,14 @@ int population_insert (population_t *p, void *pi_orig) /* {{{ */
     return (-1);
   }
 
     return (-1);
   }
 
-  num_tries = (int) ceil (log (p->individuals_num) / log (2.0));
-  for (i = 0; i < num_tries; i++)
+  do
   {
     size_t j;
 
   {
     size_t j;
 
+    int chance_j;
+    int chance_pi;
+    int chance;
+
     j = (size_t) (((double) p->individuals_num) * (rand() / (RAND_MAX + 1.0)));
 
     if (p->individuals[j].ptr == NULL)
     j = (size_t) (((double) p->individuals_num) * (rand() / (RAND_MAX + 1.0)));
 
     if (p->individuals[j].ptr == NULL)
@@ -526,7 +529,13 @@ int population_insert (population_t *p, void *pi_orig) /* {{{ */
       break;
     }
 
       break;
     }
 
-    if (pi_rating < p->individuals[j].rating)
+    /* large distance from fittest => high probability of losing. */
+    chance_j = 1 + p->individuals[j].rating - p->fittest.rating;
+    chance_pi = 1 + pi_rating - p->fittest.rating;
+
+    chance = (int) (((double) (chance_j + chance_pi))
+        * (rand() / (RAND_MAX + 1.0)));
+    if (chance < chance_j) /* j looses ;) */
     {
       void *temp0;
       int temp1;
     {
       void *temp0;
       int temp1;
@@ -539,7 +548,7 @@ int population_insert (population_t *p, void *pi_orig) /* {{{ */
       p->individuals[j].rating = pi_rating;
       pi_rating = temp1;
     }
       p->individuals[j].rating = pi_rating;
       pi_rating = temp1;
     }
-  }
+  } while (0);
 
   pthread_mutex_unlock (&p->lock);
 
 
   pthread_mutex_unlock (&p->lock);