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

ofria at myxo.css.msu.edu ofria at myxo.css.msu.edu
Mon Oct 16 18:22:07 PDT 2006


Author: ofria
Date: 2006-10-16 21:22:07 -0400 (Mon, 16 Oct 2006)
New Revision: 1049

Added:
   development/source/main/cDeme.cc
   development/source/main/cDeme.h
Modified:
   development/source/main/CMakeLists.txt
   development/source/main/SConscript
   development/source/main/cPopulation.cc
   development/source/main/cPopulation.h
   development/source/main/cPopulationCell.cc
   development/source/main/cPopulationCell.h
Log:
Abstracted demes out into a cDeme obejct to make them more modular and easier
to use.

Also added a SpawnDeme method to cPopulation that will copy a single
individual out of one deme, and inject it into a second deme (after wiping
out the existing organisms in that second deme).


Modified: development/source/main/CMakeLists.txt
===================================================================
--- development/source/main/CMakeLists.txt	2006-10-17 01:11:24 UTC (rev 1048)
+++ development/source/main/CMakeLists.txt	2006-10-17 01:22:07 UTC (rev 1049)
@@ -4,6 +4,7 @@
   avida.cc
   cAvidaConfig.cc
   cBirthChamber.cc
+  cDeme.cc
   cEnvironment.cc
   cEventList.cc
   cFitnessMatrix.cc

Modified: development/source/main/SConscript
===================================================================
--- development/source/main/SConscript	2006-10-17 01:11:24 UTC (rev 1048)
+++ development/source/main/SConscript	2006-10-17 01:22:07 UTC (rev 1049)
@@ -8,6 +8,7 @@
   'cAvidaConfig.h',
   'cAvidaContext.h',
   'cBirthChamber.h',
+  'cDeme.h',
   'cEnvironment.h',
   'cEventList.h',
   'cFitnessMatrix.h',
@@ -58,6 +59,7 @@
   'avida.cc',
   'cAvidaConfig.cc',
   'cBirthChamber.cc',
+  'cDeme.cc',
   'cEnvironment.cc',
   'cEventList.cc',
   'cFitnessMatrix.cc',

Added: development/source/main/cDeme.cc
===================================================================
--- development/source/main/cDeme.cc	2006-10-17 01:11:24 UTC (rev 1048)
+++ development/source/main/cDeme.cc	2006-10-17 01:22:07 UTC (rev 1049)
@@ -0,0 +1,39 @@
+/*
+ *  cDeme.cc
+ *  Avida
+ *
+ *  Copyright 2006 Michigan State University. All rights reserved.
+ *
+ */
+
+#include "cDeme.h"
+
+cDeme::cDeme()
+  : width(0)
+  , birth_count(0)
+{
+}
+
+cDeme::~cDeme()
+{
+}
+
+void cDeme::Setup(const tArray<int> & in_cells, int in_width)
+{
+  cell_ids = in_cells;
+  birth_count = 0;
+
+  // If width is negative, set it to the full number of cells.
+  width = in_width;
+  if (width < 1) width = cell_ids.GetSize();
+}
+
+int cDeme::GetCellID(int x, int y) const
+{
+  assert(x >= 0 && x < GetWidth());
+  assert(y >= 0 && y < GetHeight());
+
+  const int pos = y * width + x;
+  return cell_ids[pos];
+}
+

Added: development/source/main/cDeme.h
===================================================================
--- development/source/main/cDeme.h	2006-10-17 01:11:24 UTC (rev 1048)
+++ development/source/main/cDeme.h	2006-10-17 01:22:07 UTC (rev 1049)
@@ -0,0 +1,47 @@
+/*
+ *  cDeme.h
+ *  Avida
+ *
+ *  Copyright 2006 Michigan State University. All rights reserved.
+ *
+ */
+
+// DESCRIPTION:
+// Demes are groups of cells in the population that are somehow bound togehter
+// as a unit.  The deme object is used from withing cPopulation to manage these
+// groups.
+
+#ifndef cDeme_h
+#define cDeme_h
+
+#ifndef tArray_h
+#include "tArray.h"
+#endif
+
+
+class cDeme {
+private:
+  tArray<int> cell_ids;
+  int width;
+  int birth_count;
+
+public:
+  cDeme();
+  ~cDeme();
+
+  void Setup(const tArray<int> & in_cells, int in_width=-1);
+
+  int GetSize() const { return cell_ids.GetSize(); }
+  int GetCellID(int pos) const { return cell_ids[pos]; }
+  int GetCellID(int x, int y) const;
+
+  int GetWidth() const { return width; }
+  int GetHeight() const { return cell_ids.GetSize() / width; }
+
+  void Reset() { birth_count = 0; }
+  int GetBirthCount() const { return birth_count; }
+  void IncBirthCount() { birth_count++; }
+};
+
+#endif
+

Modified: development/source/main/cPopulation.cc
===================================================================
--- development/source/main/cPopulation.cc	2006-10-17 01:11:24 UTC (rev 1048)
+++ development/source/main/cPopulation.cc	2006-10-17 01:22:07 UTC (rev 1049)
@@ -199,9 +199,10 @@
 
 // This method configures demes in the population.  Demes are subgroups of
 // organisms evolved together and used in group selection experiments.
+
 bool cPopulation::SetupDemes()
 {
-  num_demes = m_world->GetConfig().NUM_DEMES.Get();
+  const int num_demes = m_world->GetConfig().NUM_DEMES.Get();
   const int birth_method = m_world->GetConfig().BIRTH_METHOD.Get();
   
   // If we are not using demes, stop here.
@@ -214,6 +215,8 @@
     return true;
   }
   
+  deme_array.Resize(num_demes);
+
   // Check to make sure all other settings are reasonable to have demes.
   // ...make sure populaiton can be divided up evenly.
   if (world_y % num_demes != 0) {
@@ -231,12 +234,21 @@
   
   const int deme_size_x = world_x;
   const int deme_size_y = world_y / num_demes;
-  deme_size = deme_size_x * deme_size_y;
+  const int deme_size = deme_size_x * deme_size_y;
   
-  // Track birth counts...
-  deme_birth_count.Resize(num_demes);
-  deme_birth_count.SetAll(0);
   
+  // Setup the deme structures.
+  tArray<int> deme_cells(deme_size);
+  for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+    for (int offset = 0; offset < deme_size; offset++) {
+      int cell_id = deme_id * deme_size + offset;
+      deme_cells[offset] = cell_id;
+      cell_array[cell_id].SetDemeID(deme_id);
+    }
+    deme_array[deme_id].Setup(deme_cells);
+  }
+
+  
   // Build walls in the population.
   for (int row_id = 0; row_id < world_y; row_id += deme_size_y) {
     // Loop through all of the cols and make the cut on each...
@@ -619,6 +631,7 @@
 
 void cPopulation::CompeteDemes(int competition_type)
 {
+  const int num_demes = deme_array.GetSize();
   
   double total_fitness = 0; 
   tArray<double> deme_fitness(num_demes); 
@@ -630,117 +643,125 @@
       break; 
     case 1:     // deme fitness = number of births
                 // Determine the scale for fitness by totaling births across demes.
-      for (int cur_deme = 0; cur_deme < num_demes; cur_deme++) {
-        deme_fitness[cur_deme] = (double) deme_birth_count[cur_deme]; 
-        total_fitness += deme_birth_count[cur_deme];
+      for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+	double cur_fitness = (double) deme_array[deme_id].GetBirthCount();
+        deme_fitness[deme_id] = cur_fitness;
+        total_fitness += cur_fitness;
       }
       break; 
     case 2:    // deme fitness = average organism fitness at the current update
-      for (int cur_deme = 0; cur_deme < num_demes; cur_deme++) {
+      for (int deme_id = 0; deme_id < num_demes; deme_id++) {
         cDoubleSum single_deme_fitness;
-        for (int i = 0; i < deme_size; i++) {
-          int cur_cell = cur_deme * deme_size + i;
+	const cDeme & cur_deme = deme_array[deme_id];
+        for (int i = 0; i < cur_deme.GetSize(); i++) {
+          int cur_cell = cur_deme.GetCellID(i);
           if (cell_array[cur_cell].IsOccupied() == false) continue;
-          cPhenotype & phenotype = GetCell(cur_cell).GetOrganism()->GetPhenotype();
+          cPhenotype & phenotype =
+	    GetCell(cur_cell).GetOrganism()->GetPhenotype();
           single_deme_fitness.Add(phenotype.GetFitness());
         } 
-        deme_fitness[cur_deme] = single_deme_fitness.Ave();
-        total_fitness += deme_fitness[cur_deme];
+        deme_fitness[deme_id] = single_deme_fitness.Ave();
+        total_fitness += deme_fitness[deme_id];
       }
       break; 
     case 3: 	// deme fitness = average mutation rate at the current update 
-      for (int cur_deme = 0; cur_deme < num_demes; cur_deme++) {
+      for (int deme_id = 0; deme_id < num_demes; deme_id++) {
         cDoubleSum single_deme_div_type;
-        for (int i = 0; i < deme_size; i++) {
-          int cur_cell = cur_deme * deme_size + i;
+	const cDeme & cur_deme = deme_array[deme_id];
+        for (int i = 0; i < cur_deme.GetSize(); i++) {
+          int cur_cell = cur_deme.GetCellID(i);
           if (cell_array[cur_cell].IsOccupied() == false) continue;
-          cPhenotype & phenotype = GetCell(cur_cell).GetOrganism()->GetPhenotype();
+          cPhenotype & phenotype =
+	    GetCell(cur_cell).GetOrganism()->GetPhenotype();
           assert(phenotype.GetDivType()>0);
           single_deme_div_type.Add(1/phenotype.GetDivType());
         }
-        deme_fitness[cur_deme] = single_deme_div_type.Ave();
-        total_fitness += deme_fitness[cur_deme];
-      } 			 	      	
+        deme_fitness[deme_id] = single_deme_div_type.Ave();
+        total_fitness += deme_fitness[deme_id];
+      }
       break; 
     case 4: 	// deme fitness = 2^(-deme fitness rank) 
               // first find all the deme fitness values ...
     {      
-      for (int cur_deme = 0; cur_deme < num_demes; cur_deme++) {
+      for (int deme_id = 0; deme_id < num_demes; deme_id++) {
         cDoubleSum single_deme_fitness;
-        for (int i = 0; i < deme_size; i++) {
-          int cur_cell = cur_deme * deme_size + i; 
+	const cDeme & cur_deme = deme_array[deme_id];
+        for (int i = 0; i < cur_deme.GetSize(); i++) {
+          int cur_cell = cur_deme.GetCellID(i);
           if (cell_array[cur_cell].IsOccupied() == false) continue;
           cPhenotype & phenotype = GetCell(cur_cell).GetOrganism()->GetPhenotype();
           single_deme_fitness.Add(phenotype.GetFitness());
         }  
-        deme_fitness[cur_deme] = single_deme_fitness.Ave();
+        deme_fitness[deme_id] = single_deme_fitness.Ave();
       }
       // ... then determine the rank of each deme based on its fitness
       tArray<double> deme_rank(num_demes);
       deme_rank.SetAll(1);
-      for (int cur_deme = 0; cur_deme < num_demes; cur_deme++) {
+      for (int deme_id = 0; deme_id < num_demes; deme_id++) {
         for (int test_deme = 0; test_deme < num_demes; test_deme++) {
-          if (deme_fitness[cur_deme] < deme_fitness[test_deme]) {
-            deme_rank[cur_deme]++;
+          if (deme_fitness[deme_id] < deme_fitness[test_deme]) {
+            deme_rank[deme_id]++;
           } 
         } 
       } 
       // ... finally, make deme fitness 2^(-deme rank)
       deme_fitness.SetAll(1);	
-      for (int cur_deme = 0; cur_deme < num_demes; cur_deme++) {
-        for (int i = 0; i < deme_rank[cur_deme]; i++) { 
-          deme_fitness[cur_deme] = deme_fitness[cur_deme]/2;
+      for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+        for (int i = 0; i < deme_rank[deme_id]; i++) { 
+          deme_fitness[deme_id] = deme_fitness[deme_id]/2;
         } 
-        total_fitness += deme_fitness[cur_deme]; 
+        total_fitness += deme_fitness[deme_id]; 
       } 
     }
-      break; 
-    case 5:    // deme fitness = average organism life fitness at the current update
-      for (int cur_deme = 0; cur_deme < num_demes; cur_deme++) {
+    break; 
+  case 5:    // deme fitness = average organism life fitness at the current update
+    for (int deme_id = 0; deme_id < num_demes; deme_id++) {
         cDoubleSum single_deme_life_fitness;
-        for (int i = 0; i < deme_size; i++) {
-          int cur_cell = cur_deme * deme_size + i;
+	const cDeme & cur_deme = deme_array[deme_id];
+        for (int i = 0; i < cur_deme.GetSize(); i++) {
+          int cur_cell = cur_deme.GetCellID(i);
           if (cell_array[cur_cell].IsOccupied() == false) continue;
           cPhenotype & phenotype = GetCell(cur_cell).GetOrganism()->GetPhenotype();
           single_deme_life_fitness.Add(phenotype.GetLifeFitness());
         }
-        deme_fitness[cur_deme] = single_deme_life_fitness.Ave();
-        total_fitness += deme_fitness[cur_deme];
-      }
-      break; 
-    case 6:     // deme fitness = 2^(-deme life fitness rank) (same as 4, but with life fitness)
-                // first find all the deme fitness values ...
+        deme_fitness[deme_id] = single_deme_life_fitness.Ave();
+        total_fitness += deme_fitness[deme_id];
+    }
+    break; 
+  case 6:     // deme fitness = 2^(-deme life fitness rank) (same as 4, but with life fitness)
+    // first find all the deme fitness values ...
     {
-      for (int cur_deme = 0; cur_deme < num_demes; cur_deme++) {
+      for (int deme_id = 0; deme_id < num_demes; deme_id++) {
         cDoubleSum single_deme_life_fitness;
-        for (int i = 0; i < deme_size; i++) {
-          int cur_cell = cur_deme * deme_size + i;
+	const cDeme & cur_deme = deme_array[deme_id];
+        for (int i = 0; i < cur_deme.GetSize(); i++) {
+          int cur_cell = cur_deme.GetCellID(i);
           if (cell_array[cur_cell].IsOccupied() == false) continue;
           cPhenotype & phenotype = GetCell(cur_cell).GetOrganism()->GetPhenotype();
           single_deme_life_fitness.Add(phenotype.GetLifeFitness());
         }
-        deme_fitness[cur_deme] = single_deme_life_fitness.Ave();
+        deme_fitness[deme_id] = single_deme_life_fitness.Ave();
       }
       // ... then determine the rank of each deme based on its fitness
       tArray<double> deme_rank(num_demes);
       deme_rank.SetAll(1);
-      for (int cur_deme = 0; cur_deme < num_demes; cur_deme++) {
+      for (int deme_id = 0; deme_id < num_demes; deme_id++) {
         for (int test_deme = 0; test_deme < num_demes; test_deme++) {
-          if (deme_fitness[cur_deme] < deme_fitness[test_deme]) {
-            deme_rank[cur_deme]++;
+          if (deme_fitness[deme_id] < deme_fitness[test_deme]) {
+            deme_rank[deme_id]++;
           }
         }
       }
       // ... finally, make deme fitness 2^(-deme rank)
       deme_fitness.SetAll(1);
-      for (int cur_deme = 0; cur_deme < num_demes; cur_deme++) {
-        for (int i = 0; i < deme_rank[cur_deme]; i++) {
-          deme_fitness[cur_deme] = deme_fitness[cur_deme]/2;
+      for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+        for (int i = 0; i < deme_rank[deme_id]; i++) {
+          deme_fitness[deme_id] = deme_fitness[deme_id]/2;
         }
-        total_fitness += deme_fitness[cur_deme];
+        total_fitness += deme_fitness[deme_id];
       }
     }
-      break;
+    break;
   } 
   
   // Pick which demes should be in the next generation.
@@ -770,42 +791,52 @@
   // Copy demes until all deme counts are 1.
   while (true) {
     // Find the next deme to copy...
-    int from_deme, to_deme;
-    for (from_deme = 0; from_deme < num_demes; from_deme++) {
-      if (deme_count[from_deme] > 1) break;
+    int from_deme_id, to_deme_id;
+    for (from_deme_id = 0; from_deme_id < num_demes; from_deme_id++) {
+      if (deme_count[from_deme_id] > 1) break;
     }
-    if (from_deme == num_demes) break; // If we don't find another deme to copy
     
-    for (to_deme = 0; to_deme < num_demes; to_deme++) {
-      if (deme_count[to_deme] == 0) break;
+    // Stop If we didn't find another deme to copy
+    if (from_deme_id == num_demes) break;
+    
+    for (to_deme_id = 0; to_deme_id < num_demes; to_deme_id++) {
+      if (deme_count[to_deme_id] == 0) break;
     }
     
     // We now have both a from and a to deme....
-    deme_count[from_deme]--;
-    deme_count[to_deme]++;
+    deme_count[from_deme_id]--;
+    deme_count[to_deme_id]++;
     
+    cDeme & from_deme = deme_array[from_deme_id];
+    cDeme & to_deme   = deme_array[to_deme_id];
+
     // Do the actual copy!
-    for (int i = 0; i < deme_size; i++) {
-      int from_cell = from_deme * deme_size + i;
-      int to_cell = to_deme * deme_size + i;
-      if (cell_array[from_cell].IsOccupied() == true) {
-        InjectClone( to_cell, *(cell_array[from_cell].GetOrganism()) );
+    for (int i = 0; i < from_deme.GetSize(); i++) {
+      int from_cell_id = from_deme.GetCellID(i);
+      int to_cell_id = to_deme.GetCellID(i);
+      if (cell_array[from_cell_id].IsOccupied() == true) {
+        InjectClone( to_cell_id, *(cell_array[from_cell_id].GetOrganism()) );
       }
     }
-    is_init[to_deme] = true;
+    is_init[to_deme_id] = true;
   }
   
   // Now re-inject all remaining demes into themselves to reset them.
-  for (int cur_deme = 0; cur_deme < num_demes; cur_deme++) {
-    if (is_init[cur_deme] == true) continue;
-    for (int i = 0; i < deme_size; i++) {
-      int cur_cell = cur_deme * deme_size + i;
-      if (cell_array[cur_cell].IsOccupied() == false) continue;
-      InjectClone( cur_cell, *(cell_array[cur_cell].GetOrganism()) );
+  for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+    if (is_init[deme_id] == true) continue;
+    cDeme & cur_deme = deme_array[deme_id];
+
+    for (int i = 0; i < cur_deme.GetSize(); i++) {
+      int cur_cell_id = cur_deme.GetCellID(i);
+      if (cell_array[cur_cell_id].IsOccupied() == false) continue;
+      InjectClone( cur_cell_id, *(cell_array[cur_cell_id].GetOrganism()) );
     }
   }
   
-  deme_birth_count.SetAll(0);
+  // Reset all deme stats to zero.
+  for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+    deme_array[deme_id].Reset();
+  }
 }
 
 
@@ -815,21 +846,26 @@
 void cPopulation::ResetDemes()
 {
   // re-inject all demes into themselves to reset them.
-  for (int cur_deme = 0; cur_deme < num_demes; cur_deme++) {
-    for (int i = 0; i < deme_size; i++) {
-      int cur_cell = cur_deme * deme_size + i;
-      if (cell_array[cur_cell].IsOccupied() == false) continue;
-      InjectClone( cur_cell, *(cell_array[cur_cell].GetOrganism()) );
+  for (int deme_id = 0; deme_id < deme_array.GetSize(); deme_id++) {
+    for (int i = 0; i < deme_array[deme_id].GetSize(); i++) {
+      int cur_cell_id = deme_array[deme_id].GetCellID(i);
+      if (cell_array[cur_cell_id].IsOccupied() == false) continue;
+      InjectClone( cur_cell_id, *(cell_array[cur_cell_id].GetOrganism()) );
     }
   }
 }
 
-// Copy the contents of one deme into another.
+
+// Copy the full contents of one deme into another.
+
 void cPopulation::CopyDeme(int deme1_id, int deme2_id)
 {
-  for (int i = 0; i < deme_size; i++) {
-    int from_cell = deme1_id * deme_size + i;
-    int to_cell = deme2_id * deme_size + i;
+  cDeme & deme1 = deme_array[deme1_id];
+  cDeme & deme2 = deme_array[deme2_id];
+
+  for (int i = 0; i < deme1.GetSize(); i++) {
+    int from_cell = deme1.GetCellID(i);
+    int to_cell = deme2.GetCellID(i);
     if (cell_array[from_cell].IsOccupied() == false) {
       KillOrganism(cell_array[to_cell]);
       continue;
@@ -839,6 +875,29 @@
 }
 
 
+// Copy a single indvidual out of a deme into a new one (which is first purged
+// of existing organisms.)
+
+void cPopulation::SpawnDeme(int deme1_id, int deme2_id)
+{
+  cDeme & deme1 = deme_array[deme1_id];
+  cDeme & deme2 = deme_array[deme2_id];
+
+  // Determine the cell to copy from and to.
+  cRandom & random = m_world->GetRandom();
+  int cell1_id = deme1.GetCellID( random.GetUInt(deme1.GetSize()) );
+  int cell2_id = deme2.GetCellID( random.GetUInt(deme2.GetSize()) );
+
+  // Clear out existing cells in target deme.
+  for (int i = 0; i < deme2.GetSize(); i++) {
+    KillOrganism(cell_array[ deme2.GetCellID(i) ]);
+  }
+
+  // And do the spawning.
+  InjectClone( cell2_id, *(cell_array[cell1_id].GetOrganism()) );    
+}
+
+
 // Print out statistics about individual demes
 
 void cPopulation::PrintDemeStats()
@@ -880,13 +939,14 @@
   const int num_inst = m_world->GetNumInstructions();
   const int num_task = environment.GetTaskLib().GetSize();
   
-  for (int cur_deme = 0; cur_deme < num_demes; cur_deme++) {
+  const int num_demes = deme_array.GetSize();
+  for (int deme_id = 0; deme_id < num_demes; deme_id++) {
     cString filename;
-    filename.Set("deme_instruction-%d.dat", cur_deme);
+    filename.Set("deme_instruction-%d.dat", deme_id);
     cDataFile & df_inst = m_world->GetDataFile(filename); 
     cString comment;
     comment.Set("Number of times each instruction is exectued in deme %d",
-                cur_deme);
+                deme_id);
     df_inst.WriteComment(comment);
     df_inst.WriteTimeStamp();
     df_inst.Write(stats.GetUpdate(), "update");
@@ -900,8 +960,9 @@
     tArray<cIntSum> single_deme_task(num_task);
     tArray<cIntSum> single_deme_inst(num_inst);
     
-    for (int i = 0; i < deme_size; i++) {
-      int cur_cell = cur_deme * deme_size + i;
+    const cDeme & cur_deme = deme_array[deme_id];
+    for (int i = 0; i < cur_deme.GetSize(); i++) {
+      int cur_cell = cur_deme.GetCellID(i);
       if (cell_array[cur_cell].IsOccupied() == false) continue;
       cPhenotype & phenotype = GetCell(cur_cell).GetOrganism()->GetPhenotype();
       single_deme_fitness.Add(phenotype.GetFitness()); 	
@@ -923,7 +984,7 @@
       }
     }
     
-    comment.Set("Deme %d", cur_deme);
+    comment.Set("Deme %d", deme_id);
     df_fit.Write(single_deme_fitness.Ave(), comment);
     df_life_fit.Write(single_deme_life_fitness.Ave(), comment);
     df_merit.Write(single_deme_merit.Ave(), comment);
@@ -932,7 +993,7 @@
     df_receiver.Write(single_deme_receiver.Sum(), comment);
     
     for (int j = 0; j < num_task; j++) {
-      comment.Set("Deme %d, Task %d", cur_deme, j);
+      comment.Set("Deme %d, Task %d", deme_id, j);
       df_task.Write((int) single_deme_task[j].Sum(), comment);
     }
     
@@ -1003,14 +1064,18 @@
     return *out_cell;
   }
   else if (birth_method == POSITION_CHILD_DEME_RANDOM) {
-    const int parent_id = parent_cell.GetID();
-    const int cur_deme = parent_id / deme_size;
-    int out_pos = m_world->GetRandom().GetUInt(deme_size) + deme_size * cur_deme;
-    while (parent_ok == false && out_pos == parent_cell.GetID()) {
-      out_pos = m_world->GetRandom().GetUInt(deme_size) + deme_size * cur_deme;
+    const int deme_id = parent_cell.GetDemeID();
+    const int deme_size = deme_array[deme_id].GetSize();
+
+    int out_pos = m_world->GetRandom().GetUInt(deme_size);
+    int out_cell_id = deme_array[deme_id].GetCellID(out_pos);
+    while (parent_ok == false && out_cell_id == parent_cell.GetID()) {
+      out_pos = m_world->GetRandom().GetUInt(deme_size);
+      out_cell_id = deme_array[deme_id].GetCellID(out_pos);
     }
-    deme_birth_count[cur_deme]++;
-    return GetCell(out_pos);    
+
+    deme_array[deme_id].IncBirthCount();
+    return GetCell(out_cell_id);    
   }
   else if (birth_method == POSITION_CHILD_PARENT_FACING) {
     return parent_cell.GetCellFaced();
@@ -1052,10 +1117,9 @@
     }
   }
   
-  if (num_demes > 0) {
-    const int parent_id = parent_cell.GetID();
-    const int cur_deme = parent_id / deme_size;
-    deme_birth_count[cur_deme]++;
+  if (deme_array.GetSize() > 0) {
+    const int deme_id = parent_cell.GetDemeID();
+    deme_array[deme_id].IncBirthCount();
   }
   
   // If there are no possibilities, return parent.

Modified: development/source/main/cPopulation.h
===================================================================
--- development/source/main/cPopulation.h	2006-10-17 01:11:24 UTC (rev 1048)
+++ development/source/main/cPopulation.h	2006-10-17 01:22:07 UTC (rev 1049)
@@ -16,6 +16,9 @@
 #ifndef cBirthChamber_h
 #include "cBirthChamber.h"
 #endif
+#ifndef cDeme_h
+#include "cDeme.h"
+#endif
 #ifndef cOrgInterface_h
 #include "cOrgInterface.h"
 #endif
@@ -72,9 +75,7 @@
   int world_x;                         // Structured population width.
   int world_y;                         // Structured population
   int num_organisms;                   // Cell count with living organisms
-  int num_demes;                       // Number of sub-groups of organisms
-  int deme_size;                       // Number of organims in a deme.
-  tArray<int> deme_birth_count;        // Track number of births in each deme.
+  tArray<cDeme> deme_array;            // Deme structure of the population.
  
   // Outside interactions...
   bool sync_events;   // Do we need to sync up the event list with population?
@@ -133,10 +134,12 @@
   void Kaboom(cPopulationCell& in_cell, int distance=0);
   void AddSellValue(const int data, const int label, const int sell_price, const int org_id, const int cell_id);
   int BuyValue(const int label, const int buy_price, const int cell_id);
+
   // Deme-related methods
   void CompeteDemes(int competition_type);
   void ResetDemes();
   void CopyDeme(int deme1_id, int deme2_id);
+  void SpawnDeme(int deme1_id, int deme2_id);
   void PrintDemeStats();
 
   // Process a single organism one instruction...

Modified: development/source/main/cPopulationCell.cc
===================================================================
--- development/source/main/cPopulationCell.cc	2006-10-17 01:11:24 UTC (rev 1048)
+++ development/source/main/cPopulationCell.cc	2006-10-17 01:22:07 UTC (rev 1049)
@@ -31,6 +31,7 @@
   , organism(in_cell.organism)
   , cur_input(in_cell.cur_input)
   , cell_id(in_cell.cell_id)
+  , deme_id(in_cell.deme_id)
   , organism_count(in_cell.organism_count)
 {
   for (int i = 0; i < nHardware::IO_SIZE; i++) input_array[i] = in_cell.input_array[i];
@@ -49,6 +50,7 @@
   for (int i = 0; i < nHardware::IO_SIZE; i++) input_array[i] = in_cell.input_array[i];
   cur_input = in_cell.cur_input;
   cell_id = in_cell.cell_id;
+  deme_id = in_cell.deme_id;
   organism_count = in_cell.organism_count;
   if (mutation_rates == NULL)
     mutation_rates = new cMutationRates(*in_cell.mutation_rates);
@@ -65,6 +67,8 @@
 {
   m_world = world;
   cell_id = in_id;
+  deme_id = -1;
+  
   if (mutation_rates == NULL)
     mutation_rates = new cMutationRates(in_rates);
   else

Modified: development/source/main/cPopulationCell.h
===================================================================
--- development/source/main/cPopulationCell.h	2006-10-17 01:11:24 UTC (rev 1048)
+++ development/source/main/cPopulationCell.h	2006-10-17 01:22:07 UTC (rev 1049)
@@ -40,6 +40,7 @@
   int cur_input;                           // Next input to give organism.
 
   int cell_id;           // Unique id for position of cell in population.
+  int deme_id;           // ID of the deme that this cell is part of.
   int organism_count;    // Total number of orgs to ever inhabit this cell.
 
 
@@ -54,6 +55,7 @@
   void operator=(const cPopulationCell& in_cell);
 
   void Setup(cWorld* world, int in_id, const cMutationRates & in_rates);
+  void SetDemeID(int in_id) { deme_id = in_id; }
   void Rotate(cPopulationCell & new_facing);
 
   cOrganism* GetOrganism() const { return organism; }
@@ -66,6 +68,7 @@
   int GetInputAt(int & input_pointer);
 
   int GetID() const { return cell_id; }
+  int GetDemeID() const { return deme_id; }
   int GetOrganismCount() const { return organism_count; }
 
   bool IsOccupied() const { return organism != NULL; }




More information about the Avida-cvs mailing list