[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