[Avida-SVN] r2481 - development/source/main

barrick at myxo.css.msu.edu barrick at myxo.css.msu.edu
Thu Mar 20 20:54:23 PDT 2008


Author: barrick
Date: 2008-03-20 23:54:23 -0400 (Thu, 20 Mar 2008)
New Revision: 2481

Modified:
   development/source/main/cAvidaConfig.h
   development/source/main/cPopulation.cc
Log:
Some deme options to allow migration to target "adjacent" demes in two flavors. Not well-tested yet.

Better fitness overflow avoidance in CompeteOrganisms.





Modified: development/source/main/cAvidaConfig.h
===================================================================
--- development/source/main/cAvidaConfig.h	2008-03-20 21:07:00 UTC (rev 2480)
+++ development/source/main/cAvidaConfig.h	2008-03-21 03:54:23 UTC (rev 2481)
@@ -310,6 +310,9 @@
   CONFIG_ADD_VAR(GERMLINE_DEL_MUT, double, 0.05, "Prob. of a deletion mutation occuring\nduring germline replication (default=0.05).");
   CONFIG_ADD_VAR(DEMES_REPLICATE_CPU_CYCLES, double, 0.0, "Replicate a deme immediately after it has used\nthis number of cpu cycles, normalized\nby number of orgs in deme (0 = OFF).");
   CONFIG_ADD_VAR(DEMES_REPLICATE_BIRTHS, int, 0, "Replicate a deme immediately after it has \nproduced this many offspring (0 = OFF).");
+  CONFIG_ADD_VAR(DEMES_REPLICATION_ONLY_RESETS, int, 0, "Kin selection mode. Deme replication really:\n1=resets deme resources\n2=rests deme resources and re-injects organisms");
+  CONFIG_ADD_VAR(DEMES_MIGRATION_TARGET_MODE, int, 0, "How do we choose what demes an org may land in when it migrates?\n0=all other demes\n1=eight adjacent neighbors\n2=two adjacent demes in list");
+  CONFIG_ADD_VAR(DEMES_NUM_X, int, 0, "Simulated number of demes in X dimension. Only used for migration. ");
 
   CONFIG_ADD_GROUP(REPRODUCTION_GROUP, "Birth and Death");
   CONFIG_ADD_VAR(BIRTH_METHOD, int, 0, "Which organism should be replaced on birth?\n0 = Random organism in neighborhood\n1 = Oldest in neighborhood\n2 = Largest Age/Merit in neighborhood\n3 = None (use only empty cells in neighborhood)\n4 = Random from population (Mass Action)\n5 = Oldest in entire population\n6 = Random within deme\n7 = Organism faced by parent\n8 = Next grid cell (id+1)\n9 = Largest energy used in entire population\n10 = Largest energy used in neighborhood");

Modified: development/source/main/cPopulation.cc
===================================================================
--- development/source/main/cPopulation.cc	2008-03-20 21:07:00 UTC (rev 2480)
+++ development/source/main/cPopulation.cc	2008-03-21 03:54:23 UTC (rev 2481)
@@ -1156,7 +1156,29 @@
     if(m_world->GetConfig().DEMES_PREVENT_STERILE.Get() && (source_deme.GetBirthCount() == 0)) {
       return;
     }
-
+    
+    //Option to bridge between kin and group selection.
+    if (m_world->GetConfig().DEMES_REPLICATION_ONLY_RESETS.Get())
+    {
+      //Reset deme (resources and births, among other things)
+      int source_deme_generation = source_deme.GetGeneration();
+      bool source_deme_resource_reset = m_world->GetConfig().DEMES_RESET_RESOURCES.Get() == 0;
+      source_deme.Reset(source_deme_generation, source_deme_resource_reset);
+      
+      //Reset all organisms in deme, by re-injecting them?
+      if (m_world->GetConfig().DEMES_REPLICATION_ONLY_RESETS.Get() == 2) {
+        for (int i=0; i<source_deme.GetSize(); i++) {
+          int cellid = source_deme.GetCellID(i);
+          if (GetCell(cellid).IsOccupied()) {          
+            int lineage = GetCell(cellid).GetOrganism()->GetLineageLabel();
+            cGenome genome = GetCell(cellid).GetOrganism()->GetGenome();
+            InjectGenome(cellid, genome, lineage);
+          }
+        }
+      }
+      return;
+    }
+    
     // Pick a target deme to replicate to, making sure that 
     // we don't try to replicate over ourself.
     int target_id = source_deme.GetID();
@@ -2196,22 +2218,73 @@
 
   //@AWC -- decide wether the child will migrate to another deme -- if migrating we ignore the birth method.  
   if ((m_world->GetConfig().MIGRATION_RATE.Get() > 0.0) //@AWC -- Pedantic test to maintain consistancy.
-      && m_world->GetRandom().P(m_world->GetConfig().MIGRATION_RATE.Get())){
-     
-      //cerr << "Attempting to migrate with rate " << m_world->GetConfig().MIGRATION_RATE.Get() << "!" << endl;
+      && m_world->GetRandom().P(m_world->GetConfig().MIGRATION_RATE.Get())) {
 
+    //cerr << "Attempting to migrate with rate " << m_world->GetConfig().MIGRATION_RATE.Get() << "!" << endl;
     int deme_id = parent_cell.GetDemeID();
+    
+    //@JEB - Different target modes
+    //Original (random OTHER deme) by @AWC
+    if (m_world->GetConfig().DEMES_MIGRATION_TARGET_MODE.Get() == 0) {  
+     
+      //get another -unadjusted- deme id
+      int rnd_deme_id = m_world->GetRandom().GetInt(deme_array.GetSize()-1);
+      
+      //if the -unadjusted- id is above the excluded id, bump it up one
+      //insures uniform prob of landing in any deme but the parent's
+      if(rnd_deme_id >= deme_id) rnd_deme_id++;
+      
+      //set the new deme_id
+      deme_id = rnd_deme_id;
+    }
+    
+    //@JEB - random OTHER deme in neighborhood (assuming torus)
+    //Extremely hacked, temporary until demes fixed
+    else if (m_world->GetConfig().DEMES_MIGRATION_TARGET_MODE.Get() == 1) {
+    
+      //get a random eight-neighbor
+      int dir = m_world->GetRandom().GetInt(8);
+      
+      // 0 = NW, 1=N, continuing clockwise....
+    
+      // Up one row
+      int x_size = m_world->GetConfig().DEMES_NUM_X.Get();
+      int y_size = (int) (m_world->GetConfig().NUM_DEMES.Get() / x_size);
 
-    //get another -unadjusted- deme id
-    int rnd_deme_id = m_world->GetRandom().GetInt(deme_array.GetSize()-1);
+      assert(y_size * x_size == m_world->GetConfig().NUM_DEMES.Get());
+
+      int x = deme_id % x_size;
+      int y = (int) (deme_id / x_size);
+
+      if ( (dir == 0) || (dir == 1) || (dir == 2) ) y--;
+      if ( (dir == 5) || (dir == 6) || (dir == 7) ) y++;
+      if ( (dir == 0) || (dir == 3) || (dir == 5) ) x--;
+      if ( (dir == 2) || (dir == 4) || (dir == 7) ) x++;
+      
+      //handle boundary conditions...
+      
+      x = (x + x_size) % x_size;
+      y = (y + y_size) % y_size;
+
+      //set the new deme_id
+      deme_id = x + x_size * y;
+
+      assert(deme_id > 0);
+      assert(deme_id > 0);
+    }
     
-    //if the -unadjusted- id is above the excluded id, bump it up one
-    //insures uniform prob of landing in any deme but the parent's
-    if(rnd_deme_id >= deme_id) rnd_deme_id++;
+    //@JEB - random deme adjacent in list
+    else if (m_world->GetConfig().DEMES_MIGRATION_TARGET_MODE.Get() == 2) {
+
+      //get a random direction to move in deme list
+      int rnd_deme_id = m_world->GetRandom().GetInt(1);
+      if (rnd_deme_id = 0) rnd_deme_id = -1;
+      
+      //set the new deme_id
+      deme_id = (deme_id + rnd_deme_id + deme_array.GetSize()) % deme_array.GetSize();
+    }
     
-    //set the new deme_id
-    deme_id = rnd_deme_id;
-
+    
     //The rest of this is essentially POSITION_CHILD_DEME_RANDOM
     const int deme_size = deme_array[deme_id].GetSize();
     
@@ -2225,8 +2298,10 @@
     deme_array[deme_id].IncBirthCount();
     GetCell(out_cell_id).SetMigrant();
     return GetCell(out_cell_id);    
-    
   }
+  
+  // Fix so range can be arbitrary and we won't accidentally include ourself as a target
+  
   // @AWC If not migrating try out global/full-deme birth methods first...
   else if (birth_method == POSITION_CHILD_FULL_SOUP_RANDOM) {
    
@@ -3658,8 +3733,12 @@
   int num_competed_orgs = 0;
 
   int num_trials = -1;
-  int dynamic_scaling = (competition_type==3);
   
+  int dynamic_scaling = 0; 
+
+  if (competition_type==3) dynamic_scaling = 1;
+  else if  (competition_type==4) dynamic_scaling = 2;
+    
   // How many trials were there? -- same for every organism
   // we just need to find one...
   for (int i = 0; i < num_cells; i++) 
@@ -3748,37 +3827,50 @@
         //Geometric Mean        
         case 0:
         case 3:
-        fitness = 1.0;
-        for (int t=0; t < trial_fitnesses.GetSize(); t++) 
-        { 
-          fitness*=trial_fitnesses[t]; 
-        }
-        fitness = exp( (1.0/((double)trial_fitnesses.GetSize())) * log(fitness) );
+        case 4:    
+          //Treat as logs to avoid overflow when multiplying very large fitnesses
+          fitness = 0;
+          for (int t=0; t < trial_fitnesses.GetSize(); t++) 
+          { 
+            fitness += log(trial_fitnesses[t]); 
+          }
+          fitness /= (double)trial_fitnesses.GetSize();
+          fitness = exp( fitness );
         break;
-        
+  
+        //Product
+        case 5:
+          //Treat as logs to avoid overflow when multiplying very large fitnesses
+          fitness = 0;
+          for (int t=0; t < trial_fitnesses.GetSize(); t++) 
+          { 
+            fitness += log(trial_fitnesses[t]); 
+          }       
+          fitness = exp( fitness );
+        break;
+         
         //Geometric Mean of normalized values
         case 1:
-        fitness = 1.0;        
-        for (int t=0; t < trial_fitnesses.GetSize(); t++) 
-        { 
-           fitness*=trial_fitnesses[t] / max_trial_fitnesses[t]; 
-        }
-        fitness = exp( (1.0/((double)trial_fitnesses.GetSize())) * log(fitness) );
+          fitness = 1.0;        
+          for (int t=0; t < trial_fitnesses.GetSize(); t++) 
+          { 
+             fitness*=trial_fitnesses[t] / max_trial_fitnesses[t]; 
+          }
+          fitness = exp( (1.0/((double)trial_fitnesses.GetSize())) * log(fitness) );
         break;
         
         //Arithmetic Mean
         case 2:
-        fitness = 0;
-        for (int t=0; t < trial_fitnesses.GetSize(); t++) 
-        { 
-          fitness+=trial_fitnesses[t]; 
-        }
-        fitness /= (double)trial_fitnesses.GetSize();
+          fitness = 0;
+          for (int t=0; t < trial_fitnesses.GetSize(); t++) 
+          { 
+            fitness+=trial_fitnesses[t]; 
+          }
+          fitness /= (double)trial_fitnesses.GetSize();
         break;
       
         default:
-        cout << "Unknown CompeteOrganisms method!" << endl;
-        exit(1);
+          m_world->GetDriver().RaiseFatalException(1, "Unknown CompeteOrganisms method");
       }
       if (m_world->GetVerbosity() >= VERBOSE_DETAILS) cout << "Trial fitness in cell " << i << " = " << fitness << endl;
       org_fitness[i] = fitness;
@@ -3790,25 +3882,48 @@
   }
   average_fitness = total_fitness / num_competed_orgs;
  
-  //Rescale by the geometric mean of the difference from the top score and the median
-  if ( dynamic_scaling )
-  {
+  //Rescale by the geometric mean of the difference from the top score and the average
+  if ( dynamic_scaling == 1 ) {
     int num_org_not_max = 0;
-    double dynamic_factor = 0;
-    for (int i = 0; i < num_cells; i++) 
-    {
-      if (GetCell(i).IsOccupied())
-      {
-          if (org_fitness[i] != highest_fitness)
-          {
-            num_org_not_max++;
-            dynamic_factor += log(highest_fitness - org_fitness[i]);
-            //cout << "Time scaling factor " << time_scaling_factor << endl;
-          }
+    double dynamic_factor = 1.0;
+    if (highest_fitness > 0) {
+      dynamic_factor = 2/highest_fitness;
+    }
+    
+    total_fitness = 0;
+    for (int i = 0; i < num_cells; i++) {
+      if ( GetCell(i).IsOccupied() ) {
+        org_fitness[i] *= dynamic_factor;
+        total_fitness += org_fitness[i];
       }
     }
   }
   
+  // Rescale geometric mean to 1
+  else if ( dynamic_scaling == 2 ) {
+    int num_org = 0;
+    double dynamic_factor = 1.0;
+    for (int i = 0; i < num_cells; i++) {
+      if ( GetCell(i).IsOccupied() && (org_fitness[i] > 0.0)) {
+        num_org++;
+        dynamic_factor += log(org_fitness[i]);
+      }
+    }
+        
+    cout << "Scaling factor = " << dynamic_factor << endl;
+    if (num_org > 0) dynamic_factor = exp(dynamic_factor / (double)num_org);
+    cout << "Scaling factor = " << dynamic_factor << endl;
+    
+    total_fitness = 0;
+
+    for (int i = 0; i < num_cells; i++) {
+      if ( GetCell(i).IsOccupied() ) {
+        org_fitness[i] /= dynamic_factor;
+        total_fitness += org_fitness[i];
+      }
+    }
+  }
+  
   // Pick which orgs should be in the next generation. (Filling all cells)
   tArray<int> new_orgs(num_cells);
   for (int i = 0; i < num_cells; i++) {




More information about the Avida-cvs mailing list