src/libpopulation.c: Changed insert code for more variance.
[libpopulation.git] / src / libpopulation.c
index c5d3c4e..aa5b9dc 100644 (file)
@@ -511,11 +511,14 @@ int population_insert (population_t *p, void *pi_orig) /* {{{ */
     return (-1);
   }
 
-  num_tries = (int) ceil (log (p->individuals_num) / log (2.0));
-  for (i = 0; i < num_tries; i++)
+  do
   {
     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)
@@ -526,7 +529,13 @@ int population_insert (population_t *p, void *pi_orig) /* {{{ */
       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;
@@ -539,7 +548,7 @@ int population_insert (population_t *p, void *pi_orig) /* {{{ */
       p->individuals[j].rating = pi_rating;
       pi_rating = temp1;
     }
-  }
+  } while (0);
 
   pthread_mutex_unlock (&p->lock);