[Avida-SVN] r1330 - in branches/dkdev: Avida.xcodeproj source/main source/tools

dknoester at myxo.css.msu.edu dknoester at myxo.css.msu.edu
Sat Feb 17 17:53:22 PST 2007


Author: dknoester
Date: 2007-02-17 20:53:22 -0500 (Sat, 17 Feb 2007)
New Revision: 1330

Added:
   branches/dkdev/source/tools/cTopology.h
Modified:
   branches/dkdev/Avida.xcodeproj/project.pbxproj
   branches/dkdev/source/main/cPopulation.cc
   branches/dkdev/source/main/cPopulation.h
   branches/dkdev/source/main/cPopulationCell.cc
   branches/dkdev/source/main/nGeometry.h
   branches/dkdev/source/tools/tArray.h
Log:
Merge: r1154:1155 from avida/branches/coopcomm; changes to building cell topologies in demes.

Modified: branches/dkdev/Avida.xcodeproj/project.pbxproj
===================================================================
--- branches/dkdev/Avida.xcodeproj/project.pbxproj	2007-02-18 01:22:10 UTC (rev 1329)
+++ branches/dkdev/Avida.xcodeproj/project.pbxproj	2007-02-18 01:53:22 UTC (rev 1330)
@@ -245,6 +245,7 @@
 		70F7DE6D09296616009E311D /* cSpeciesControl.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70F7DE6A09296613009E311D /* cSpeciesControl.cc */; };
 		70F7DE7409296794009E311D /* cGenotype_BirthData.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70F7DE700929678E009E311D /* cGenotype_BirthData.cc */; };
 		DCC3166107628531008F7A48 /* avida.cc in Sources */ = {isa = PBXBuildFile; fileRef = DCC3109C0762539E008F7A48 /* avida.cc */; };
+		E08178BA0B3DCB9600B474B6 /* cTopology.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = E08178B90B3DCB9600B474B6 /* cTopology.h */; };
 		E626209E0A372C2A00C07685 /* SaveLoadActions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 708051A80A1F65FE00CBB8B6 /* SaveLoadActions.cc */; };
 /* End PBXBuildFile section */
 
@@ -288,6 +289,7 @@
 				7049F3710A66AD7E00640512 /* default-sex-classic.org in CopyFiles */,
 				7049F3720A66AD7E00640512 /* default-smt.org in CopyFiles */,
 				7049F3730A66AD7E00640512 /* default-transsmt.org in CopyFiles */,
+				E08178BA0B3DCB9600B474B6 /* cTopology.h in CopyFiles */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -793,7 +795,8 @@
 		DCC315CF076253A5008F7A48 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
 		DCC315D0076253A5008F7A48 /* task_event_gen.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = task_event_gen.cc; sourceTree = "<group>"; };
 		DCC315D1076253A5008F7A48 /* task_event_gen.old.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = task_event_gen.old.cc; sourceTree = "<group>"; };
-		DCC3164D07626CF3008F7A48 /* avida */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = avida; sourceTree = BUILT_PRODUCTS_DIR; };
+		DCC3164D07626CF3008F7A48 /* avida */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = avida; sourceTree = BUILT_PRODUCTS_DIR; };
+		E08178B90B3DCB9600B474B6 /* cTopology.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cTopology.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -1405,6 +1408,7 @@
 				700E11BC0A0815B600B604CD /* cDataEntry.cc */,
 				70B08B9008FB2E6B00FC65FE /* cTools.cc */,
 				70B08B9108FB2E6B00FC65FE /* cWeightedIndex.cc */,
+				E08178B90B3DCB9600B474B6 /* cTopology.h */,
 				70B08B8008FB2E5500FC65FE /* cTools.h */,
 				70B08B8108FB2E5500FC65FE /* cUInt.h */,
 				70B08B8208FB2E5500FC65FE /* cWeightedIndex.h */,

Modified: branches/dkdev/source/main/cPopulation.cc
===================================================================
--- branches/dkdev/source/main/cPopulation.cc	2007-02-18 01:22:10 UTC (rev 1329)
+++ branches/dkdev/source/main/cPopulation.cc	2007-02-18 01:53:22 UTC (rev 1330)
@@ -36,11 +36,13 @@
 #include "cStats.h"
 #include "cTaskEntry.h"
 #include "cWorld.h"
+#include "cTopology.h"
 
 #include <fstream>
 #include <vector>
 #include <algorithm>
 #include <set>
+#include <functional>
 
 #include <float.h>
 #include <math.h>
@@ -54,101 +56,78 @@
 , resource_count(world->GetEnvironment().GetResourceLib().GetSize())
 , birth_chamber(world)
 , environment(world->GetEnvironment())
+, world_x(world->GetConfig().WORLD_X.Get())
+, world_y(world->GetConfig().WORLD_Y.Get())
 , num_organisms(0)
+, num_demes(m_world->GetConfig().NUM_DEMES.Get())
 , sync_events(false)
 {
-  // Avida specific information.
-  world_x = world->GetConfig().WORLD_X.Get();
-  world_y = world->GetConfig().WORLD_Y.Get();
-  int geometry = world->GetConfig().WORLD_GEOMETRY.Get();
+  const int geometry = world->GetConfig().WORLD_GEOMETRY.Get();
   const int num_cells = world_x * world_y;
-
-  // Print out world details
-  if (world->GetVerbosity() > VERBOSE_NORMAL) {
-    cout << "Building world " << world_x << "x" << world_y << " = " << num_cells << " organisms." << endl;
-    if (geometry == nGeometry::GRID) {
-      cout << "Geometry: Bounded grid" << endl;
-    } else if (geometry == nGeometry::TORUS) {
-      cout << "Geometry: Torus" << endl;
-    } else {
-      cout << "Geometry: Unknown" << endl;
-    }
-    cout << endl;
+  const int birth_method = m_world->GetConfig().BIRTH_METHOD.Get();
+  
+  // Error checking for demes vs. non-demes setup.
+  if(num_demes > 0) {
+    assert(world_y % num_demes == 0);
+    assert(birth_method != POSITION_CHILD_FULL_SOUP_ELDEST);
+    assert(birth_method != POSITION_CHILD_FULL_SOUP_ELDEST);
+  } else {
+    assert(birth_method != POSITION_CHILD_DEME_RANDOM);
+    num_demes = 1; // One population == one deme.
   }
+
+  // Track birth counts...
+  deme_birth_count.Resize(num_demes);
+  deme_birth_count.SetAll(0);
   
+  const int deme_size_x = world_x;
+  const int deme_size_y = world_y / num_demes;
+  deme_size = deme_size_x * deme_size_y;
+  
   cell_array.Resize(num_cells);
   resource_count.ResizeSpatialGrids(world_x, world_y);
   market.Resize(MARKET_SIZE);
   
-  bool bottom_flag, top_flag, right_flag, left_flag;
-  for (int cell_id = 0; cell_id < num_cells; cell_id++) {
-    int x = cell_id % world_x;
-    int y = cell_id / world_x;
-    cell_array[cell_id].Setup(world, cell_id, environment.GetMutRates());
-    
-    
-    if ((y == 0) && (geometry == nGeometry::GRID)) {
-      bottom_flag = false;
-    } else {
-      bottom_flag = true;
-    }
-    if ((y == world_y-1) && (geometry == nGeometry::GRID)) {
-      top_flag = false;
-    } else {
-      top_flag = true;
-    }
-    if ((x == 0) && (geometry == nGeometry::GRID)) {
-      left_flag = false;
-    } else {
-      left_flag = true;
-    }
-    if ((x == world_x-1) && (geometry == nGeometry::GRID)) {
-      right_flag = false;
-    } else {
-      right_flag = true;
-    }
- 
-    // Setup the connection list for each cell. (Clockwise from -1 to 1)
-    
-    tList<cPopulationCell> & conn_list=cell_array[cell_id].ConnectionList();
-    if (bottom_flag && left_flag) {
-      conn_list.Push(&(cell_array[GridNeighbor(cell_id,world_x,world_y, -1, -1)]));
-    }
-    if (bottom_flag) {
-      conn_list.Push(&(cell_array[GridNeighbor(cell_id,world_x,world_y,  0, -1)]));
-    }
-    if (bottom_flag && right_flag) {
-      conn_list.Push(&(cell_array[GridNeighbor(cell_id,world_x,world_y, +1, -1)]));
-    }
-    if (right_flag) {
-      conn_list.Push(&(cell_array[GridNeighbor(cell_id,world_x,world_y, +1,  0)]));
-    }
-    if (top_flag && right_flag) {
-      conn_list.Push(&(cell_array[GridNeighbor(cell_id,world_x,world_y, +1, +1)]));
-    }
-    if (top_flag) {
-      conn_list.Push(&(cell_array[GridNeighbor(cell_id,world_x,world_y,  0, +1)]));
-    }
-    if (top_flag && left_flag) {
-      conn_list.Push(&(cell_array[GridNeighbor(cell_id,world_x,world_y, -1, +1)]));
-    }
-    if (left_flag) {
-      conn_list.Push(&(cell_array[GridNeighbor(cell_id,world_x,world_y, -1,  0)]));
-    }
-
-    // Setup the reaper queue...
+  // Setup the cells.  Do things that are not dependent upon topology here.
+  for(int i=0; i<num_cells; ++i) {
+    cell_array[i].Setup(world, i, environment.GetMutRates());
+    // Setup the reaper queue.
     if (world->GetConfig().BIRTH_METHOD.Get() == POSITION_CHILD_FULL_SOUP_ELDEST) {
-      reaper_queue.Push(&(cell_array[cell_id]));
+      reaper_queue.Push(&(cell_array[i]));
     }
+  }                         
+  
+  // Setup the topology.
+  // What we're doing here is chopping the cell_array up into num_demes pieces.
+  // Note that having 0 demes (one population) is the same as having 1 deme.  Then
+  // we send the cells that comprise each deme into the topology builder.
+  for(int i=0; i<num_cells; i+=deme_size) {
+    switch(geometry) {
+      // We're cheating here; we're using the random access nature of an iterator
+      // to index beyond the end of the cell_array.
+      case nGeometry::GRID: {
+        build_grid(&cell_array.begin()[i], &cell_array.begin()[i+deme_size], 
+                   deme_size_x, deme_size_y);
+        break;
+      }
+      case nGeometry::TORUS: {
+        build_torus(&cell_array.begin()[i], &cell_array.begin()[i+deme_size], 
+                    deme_size_x, deme_size_y);
+        break;
+      }
+      case nGeometry::CLIQUE: {
+        build_clique(&cell_array.begin()[i], &cell_array.begin()[i+deme_size], 
+                   deme_size_x, deme_size_y);
+        break;
+      }
+      default: {
+        assert(false);
+      }
+    }
   }
   
   BuildTimeSlicer(0);
   
-  if (SetupDemes() == false) {
-    cerr << "Error: Failed to setup demes.  Exiting..." << endl;
-    exit(1);
-  }
-  
   // Setup the resources...
   const cResourceLib & resource_lib = environment.GetResourceLib();
   for (int i = 0; i < resource_lib.GetSize(); i++) {
@@ -197,75 +176,8 @@
 }
 
 
-// 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 birth_method = m_world->GetConfig().BIRTH_METHOD.Get();
-  
-  // If we are not using demes, stop here.
-  if (num_demes == 0) {
-    if (birth_method == POSITION_CHILD_DEME_RANDOM) {
-      cerr << "Using position method that requires demes, but demes are off."
-      << endl;
-      return false;
-    }
-    return true;
-  }
-  
-  // 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) {
-    cerr << "World Y size of " << world_y
-    << " cannot be divided into " << num_demes << " demes." << endl;
-    return false;
-  }
-  
-  // ...make sure we are using a legal birth method.
-  if (birth_method == POSITION_CHILD_FULL_SOUP_ELDEST ||
-      birth_method == POSITION_CHILD_FULL_SOUP_RANDOM) {
-    cerr << "Illegal birth method " << birth_method << " for use with demes." << endl;
-    return false;
-  }
-  
-  const int deme_size_x = world_x;
-  const int deme_size_y = world_y / num_demes;
-  deme_size = deme_size_x * deme_size_y;
-  
-  // Track birth counts...
-  deme_birth_count.Resize(num_demes);
-  deme_birth_count.SetAll(0);
-  
-  // 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...
-    for (int col_id = 0; col_id < world_x; col_id++) {
-      int idA = row_id * world_x + col_id;
-      int idB  = GridNeighbor(idA, world_x, world_y,  0, -1);
-      int idA0 = GridNeighbor(idA, world_x, world_y, -1,  0);
-      int idA1 = GridNeighbor(idA, world_x, world_y,  1,  0);
-      int idB0 = GridNeighbor(idA, world_x, world_y, -1, -1);
-      int idB1 = GridNeighbor(idA, world_x, world_y,  1, -1);
-      cPopulationCell & cellA = GetCell(idA);
-      cPopulationCell & cellB = GetCell(idB);
-      tList<cPopulationCell> & cellA_list = cellA.ConnectionList();
-      tList<cPopulationCell> & cellB_list = cellB.ConnectionList();
-      cellA_list.Remove(&GetCell(idB));
-      cellA_list.Remove(&GetCell(idB0));
-      cellA_list.Remove(&GetCell(idB1));
-      cellB_list.Remove(&GetCell(idA));
-      cellB_list.Remove(&GetCell(idA0));
-      cellB_list.Remove(&GetCell(idA1));
-    }
-  }
-  
-  return true;
-}
-
 // Activate the child, given information from the parent.
 // Return true if parent lives through this process.
-
 bool cPopulation::ActivateOffspring(cAvidaContext& ctx, cGenome& child_genome, cOrganism& parent_organism)
 {
   assert(&parent_organism != NULL);
@@ -747,8 +659,8 @@
         }
         total_fitness += deme_fitness[cur_deme];
       }
-    }
       break;
+    }
   } 
   
   // Pick which demes should be in the next generation.
@@ -819,7 +731,6 @@
 
 // Reset Demes goes through each deme and resets the individual organisms as
 // if they were just injected into the population.
-
 void cPopulation::ResetDemes()
 {
   // re-inject all demes into themselves to reset them.

Modified: branches/dkdev/source/main/cPopulation.h
===================================================================
--- branches/dkdev/source/main/cPopulation.h	2007-02-18 01:22:10 UTC (rev 1329)
+++ branches/dkdev/source/main/cPopulation.h	2007-02-18 01:53:22 UTC (rev 1330)
@@ -116,9 +116,6 @@
   cPopulation(cWorld* world);
   ~cPopulation();
 
-  // Extra Setup...
-  bool SetupDemes();
-
   // Activate the offspring of an organism in the population
   bool ActivateOffspring(cAvidaContext& ctx, cGenome& child_genome, cOrganism& parent_organism);
   bool ActivateParasite(cOrganism& parent, const cGenome& injected_code);

Modified: branches/dkdev/source/main/cPopulationCell.cc
===================================================================
--- branches/dkdev/source/main/cPopulationCell.cc	2007-02-18 01:22:10 UTC (rev 1329)
+++ branches/dkdev/source/main/cPopulationCell.cc	2007-02-18 01:53:22 UTC (rev 1330)
@@ -74,15 +74,10 @@
 void cPopulationCell::Rotate(cPopulationCell & new_facing)
 {
   // @CAO Note, this breaks avida if new_facing is not in connection_list
-
-#ifdef DEBUG
-  int scan_count = 0;
-#endif
-  while (connection_list.GetFirst() != &new_facing) {
+  int scan_count=0;
+  while(connection_list.GetFirst() != &new_facing) {
     connection_list.CircNext();
-#ifdef DEBUG
     assert(++scan_count < connection_list.GetSize());
-#endif
   }
 }
 

Modified: branches/dkdev/source/main/nGeometry.h
===================================================================
--- branches/dkdev/source/main/nGeometry.h	2007-02-18 01:22:10 UTC (rev 1329)
+++ branches/dkdev/source/main/nGeometry.h	2007-02-18 01:53:22 UTC (rev 1330)
@@ -14,7 +14,8 @@
   enum {
     GLOBAL = 0,
     GRID,
-    TORUS
+    TORUS,
+    CLIQUE
   };
 }
 

Copied: branches/dkdev/source/tools/cTopology.h (from rev 1155, branches/coopcomm/source/tools/cTopology.h)
===================================================================
--- branches/coopcomm/source/tools/cTopology.h	2006-12-27 18:26:59 UTC (rev 1155)
+++ branches/dkdev/source/tools/cTopology.h	2007-02-18 01:53:22 UTC (rev 1330)
@@ -0,0 +1,88 @@
+/*! Builds different topologies out of ranges of cells.
+
+Avida; cTopology.h
+Copyright 2005-2006 Michigan State University. All rights reserved.
+
+This file contains templated algorithms that create a particular cell
+topology out of a given range of cells.  In every case, the range of cells is 
+specified by a begin/end iterator pair.
+*/
+
+
+/*! Builds a torus topology out of the cells betwen the iterators.
+In a torus, each cell is connected to up to 8 neighbors (including diagonals), 
+and connections DO wrap around the logical edges of the torus.
+*/
+template< typename InputIterator >
+void build_torus(InputIterator begin, InputIterator end, unsigned int rowSize, unsigned int colSize) {
+  // Get the offset from the start of this range.  This is used to modify the 
+  // parameters and return for GridNeighbor.
+  int offset = begin->GetID();
+  
+  for(InputIterator i=begin; i!=end; ++i) {
+    // The majority of all connections.
+    i->ConnectionList().Push(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, -1, 0)]);
+    i->ConnectionList().Push(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, -1, 1)]);
+    i->ConnectionList().Push(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 0, 1)]);
+    i->ConnectionList().Push(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 1, 1)]);
+    i->ConnectionList().Push(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 1, 0)]);
+    i->ConnectionList().Push(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 1, -1)]);
+    i->ConnectionList().Push(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 0, -1)]);
+    i->ConnectionList().Push(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, -1, -1)]);
+  }
+}
+
+
+/*! Builds a grid topology out of the cells betwen the iterators.
+In a grid, each cell is connected to up to 8 neighbors (including diagonals), 
+and connections do NOT wrap around the logical edges of the grid.
+*/
+template< typename InputIterator >
+void build_grid(InputIterator begin, InputIterator end, unsigned int rowSize, unsigned int colSize) {
+  // Start with a torus.
+  build_torus(begin, end, rowSize, colSize);
+  int offset = begin->GetID();
+
+  // And now remove the connections that wrap around.
+  for(InputIterator i=begin; i!=end; ++i) {
+    int id = i->GetID();
+    unsigned int x = (id-offset) % colSize;
+    unsigned int y = (id-offset) / colSize;
+    
+    if(x==0) {
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, -1, -1)]);
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, -1, 0)]);
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, -1, 1)]);
+    }
+    if(x==(colSize-1)) {
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 1, -1)]);
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 1, 0)]);
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 1, 1)]);      
+    }
+    if(y==0) {
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, -1, -1)]);
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 0, -1)]);
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 1, -1)]);      
+    }
+    if(y==(rowSize-1)) {
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, -1, 1)]);
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 0, 1)]);
+      i->ConnectionList().Remove(&begin[GridNeighbor(i->GetID()-offset, colSize, rowSize, 1, 1)]);      
+    }
+  }
+}
+
+
+/*! Builds a clique topology out of the cells betwen the iterators.
+In a clique, each cell is connected to all other cells in the given range.
+*/
+template< typename InputIterator >
+void build_clique(InputIterator begin, InputIterator end, unsigned int rowSize, unsigned int colSize) {
+  for(InputIterator i=begin; i!=end; ++i) {
+    for(InputIterator j=begin; j!=end; ++j) {
+      if(j!=i) {
+        i->ConnectionList().Push(j);
+      }
+    }
+  }
+}

Modified: branches/dkdev/source/tools/tArray.h
===================================================================
--- branches/dkdev/source/tools/tArray.h	2007-02-18 01:22:10 UTC (rev 1329)
+++ branches/dkdev/source/tools/tArray.h	2007-02-18 01:53:22 UTC (rev 1330)
@@ -33,11 +33,26 @@
   int m_size; // Number of Elements
 
 public:
+  typedef T* iterator; //!< STL-compatible iterator.
+  typedef const T* const_iterator; //!< STL-compatible const_iterator.
+    
   explicit tArray(const int size = 0) : m_data(NULL), m_size(0) { ResizeClear(size); }
   tArray(const tArray& rhs) : m_data(NULL), m_size(0) { this->operator=(rhs); }
 
   ~tArray() { delete [] m_data; }
 
+  //! Returns an iterator to the beginning of the tArray.
+  inline iterator begin() { return m_data; }
+
+  //! Returns an iterator just past the end of the tArray.
+  inline iterator end() { return m_data + m_size; }
+
+  //! Returns a const_iterator to the beginning of the tArray.
+  inline const_iterator begin() const { return m_data; }
+
+  //! Returns a const_iterator just past the end of the tArray.
+  inline const_iterator end() const { return m_data + m_size; }  
+  
   tArray& operator=(const tArray& rhs) {
     if (m_size != rhs.GetSize())  ResizeClear(rhs.GetSize());
     for(int i = 0; i < m_size; i++) m_data[i] = rhs[i];




More information about the Avida-cvs mailing list