[Avida-SVN] r2512 - in development/source: actions main
barrick at myxo.css.msu.edu
barrick at myxo.css.msu.edu
Tue Apr 1 13:45:48 PDT 2008
Author: barrick
Date: 2008-04-01 16:45:48 -0400 (Tue, 01 Apr 2008)
New Revision: 2512
Modified:
development/source/actions/PrintActions.cc
development/source/main/cAvidaConfig.h
development/source/main/cDeme.cc
development/source/main/cDeme.h
development/source/main/cPhenotype.cc
development/source/main/cPopulation.cc
development/source/main/cPopulation.h
development/source/main/cStats.cc
development/source/main/cStats.h
Log:
Pulled a few parts out of cPopulation::PositionChild() into separate functions. Split my deme migration code from Art's so that I can PREFER_EMPTY in the deme being migrated to. Mine uses DEMES_MIGRATION_RATE, Art's uses MIGRATION_RATE.
New stat files for tracking tasks and reactions done in a deme's lifetime (basically a deme-wide phenotype).
Option to replicate demes on a number of orgs (b/c you can't tell from your birth count how many orgs you have when migration is happening).
Modified: development/source/actions/PrintActions.cc
===================================================================
--- development/source/actions/PrintActions.cc 2008-04-01 20:20:46 UTC (rev 2511)
+++ development/source/actions/PrintActions.cc 2008-04-01 20:45:48 UTC (rev 2512)
@@ -96,6 +96,9 @@
STATS_OUT_FILE(PrintCompetitionData, competition.dat );
STATS_OUT_FILE(PrintDemeReplicationData, deme_repl.dat );
STATS_OUT_FILE(PrintDemeFounders, deme_founders.dat );
+STATS_OUT_FILE(PrintDemeTasks, deme_tasks.dat );
+STATS_OUT_FILE(PrintDemeTasksExe, deme_tasks_exe.dat );
+STATS_OUT_FILE(PrintDemeReactions, deme_reactions.dat );
STATS_OUT_FILE(PrintGermlineData, germline.dat );
// @WRE: Added output event for collected visit counts
STATS_OUT_FILE(PrintCellVisitsData, visits.dat );
@@ -2681,7 +2684,10 @@
action_lib->Register<cActionPrintDemeFounders>("PrintDemeFounders");
action_lib->Register<cActionPrintGermlineData>("PrintGermlineData");
action_lib->Register<cActionSaveDemeFounders>("SaveDemeFounders");
-
+ action_lib->Register<cActionPrintDemeTasks>("PrintDemeTasksData");
+ action_lib->Register<cActionPrintDemeTasksExe>("PrintDemeTasksExeData");
+ action_lib->Register<cActionPrintDemeReactions>("PrintDemeReactionData");
+
//Coalescence Clade Actions
action_lib->Register<cActionPrintCCladeCounts>("PrintCCladeCounts");
action_lib->Register<cActionPrintCCladeFitnessHistogram>("PrintCCladeFitnessHistogram");
Modified: development/source/main/cAvidaConfig.h
===================================================================
--- development/source/main/cAvidaConfig.h 2008-04-01 20:20:46 UTC (rev 2511)
+++ development/source/main/cAvidaConfig.h 2008-04-01 20:45:48 UTC (rev 2512)
@@ -310,8 +310,10 @@
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_REPLICATE_ORGS, int, 0, "Replicate a deme immediately once it reaches a\ncertain number of organisms (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_MIGRATION_RATE, double, 0.0, "Probability of an offspring being born in a different deme.");
+ CONFIG_ADD_VAR(DEMES_MIGRATION_METHOD, 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_VAR(DEMES_SEED_METHOD, int, 0, "Deme seeding method.\n0=maintain old consistency\n1=new method using genotypes");
CONFIG_ADD_VAR(DEMES_DIVIDE_METHOD, int, 0, "Deme divide method. Only works with DEMES_SEED_METHOD 1\n0=replace and target demes\n1= replace target deme, reset source deme to founders\n2=replace target deme, leave source deme unchanged");
Modified: development/source/main/cDeme.cc
===================================================================
--- development/source/main/cDeme.cc 2008-04-01 20:20:46 UTC (rev 2511)
+++ development/source/main/cDeme.cc 2008-04-01 20:45:48 UTC (rev 2512)
@@ -23,6 +23,7 @@
#include "cDeme.h"
#include "cClassificationManager.h"
+#include "cEnvironment.h"
#include "cGenotype.h"
#include "cOrganism.h"
#include "cPhenotype.h"
@@ -42,6 +43,17 @@
_current_merit = 1.0;
_next_merit = 1.0;
+ const int num_tasks = m_world->GetEnvironment().GetNumTasks();
+ const int num_reactions = m_world->GetNumReactions();
+ cur_task_count.Resize(num_tasks);
+ cur_task_count.SetAll(0);
+ cur_reaction_count.ResizeClear(num_reactions);
+ cur_reaction_count.SetAll(0);
+ last_task_count.ResizeClear(num_tasks);
+ last_task_count.SetAll(0);
+ last_reaction_count.ResizeClear(num_reactions);
+ last_reaction_count.SetAll(0);
+
// If width is negative, set it to the full number of cells.
width = in_width;
if (width < 1) width = cell_ids.GetSize();
@@ -130,6 +142,9 @@
time_used = 0;
birth_count = 0;
cur_normalized_time_used = 0;
+
+ cur_task_count.SetAll(0);
+ cur_reaction_count.SetAll(0);
if(resetResources) deme_resource_count.ReinitializeResources();
}
@@ -142,6 +157,9 @@
gestation_time = parent_deme.GetTimeUsed();
last_normalized_time_used = parent_deme.GetNormalizedTimeUsed();
+ last_task_count = cur_task_count;
+ last_reaction_count = cur_reaction_count;
+
Reset(resetResources, deme_energy);
}
Modified: development/source/main/cDeme.h
===================================================================
--- development/source/main/cDeme.h 2008-04-01 20:20:46 UTC (rev 2511)
+++ development/source/main/cDeme.h 2008-04-01 20:45:48 UTC (rev 2512)
@@ -48,7 +48,7 @@
tArray<int> cell_ids;
int width; //!< Width of this deme.
-// The following should be moved to cDemePhenotype
+// The following should be moved to cDemePhenotype / cPopulationPhenotype
int birth_count; //!< Number of organisms that have been born into this deme since reset.
int org_count; //!< Number of organisms are currently in this deme.
int _age; //!< Age of this deme, in updates.
@@ -59,6 +59,11 @@
double cur_normalized_time_used; // normalized by merit and number of orgs
double last_normalized_time_used;
+ tArray<int> cur_task_count;
+ tArray<int> cur_reaction_count;
+ tArray<int> last_task_count;
+ tArray<int> last_reaction_count;
+
// End of phenotypic traits
cGermline _germline; //!< The germline for this deme, if used.
@@ -98,7 +103,7 @@
void Reset(bool resetResources = true, double deme_energy = 0.0); //! used to pass energy to offspring deme
void DivideReset(cDeme& parent_deme, bool resetResources = true, double deme_energy = 0.0);
-
+
//! Kills all organisms currently in this deme.
void KillAll();
int GetBirthCount() const { return birth_count; }
@@ -129,7 +134,14 @@
const cMerit& GetDemeMerit() const { return _current_merit; }
//! Retrieve this deme's heritable merit.
const cMerit& GetHeritableDemeMerit() const { return _next_merit; }
-
+
+
+ void AddCurTask(int task_num) { cur_task_count[task_num]++; }
+ void AddCurReaction (int reaction_num) { cur_reaction_count[reaction_num]++; }
+
+ const tArray<int>& GetLastTaskCount() const { return last_task_count; }
+ const tArray<int>& GetLastReactionCount() const { return last_reaction_count; }
+
bool HasDemeMerit() const { return _current_merit.GetDouble() != 1.0; }
// -= Update support =-
Modified: development/source/main/cPhenotype.cc
===================================================================
--- development/source/main/cPhenotype.cc 2008-04-01 20:20:46 UTC (rev 2511)
+++ development/source/main/cPhenotype.cc 2008-04-01 20:45:48 UTC (rev 2512)
@@ -1011,6 +1011,14 @@
deme_bonus *= result.GetMultDemeBonus();
deme_bonus += result.GetAddDemeBonus();
deme->UpdateHeritableDemeMerit(deme_bonus);
+
+ //also count tasks/reactions
+ for (int i = 0; i < num_tasks; i++) {
+ if (result.TaskDone(i) == true) deme->AddCurTask(i);
+ }
+ for (int i = 0; i < num_reactions; i++) {
+ if (result.ReactionTriggered(i) == true) deme->AddCurReaction(i);
+ }
}
// Update the energy bonus
Modified: development/source/main/cPopulation.cc
===================================================================
--- development/source/main/cPopulation.cc 2008-04-01 20:20:46 UTC (rev 2511)
+++ development/source/main/cPopulation.cc 2008-04-01 20:45:48 UTC (rev 2512)
@@ -2002,7 +2002,9 @@
if (m_world->GetConfig().DEMES_REPLICATE_CPU_CYCLES.Get()
&& (deme.GetTimeUsed() >= m_world->GetConfig().DEMES_REPLICATE_CPU_CYCLES.Get())) ReplicateDeme(deme);
else if (m_world->GetConfig().DEMES_REPLICATE_BIRTHS.Get()
- && (deme.GetBirthCount() >= m_world->GetConfig().DEMES_REPLICATE_BIRTHS.Get())) ReplicateDeme(deme);
+ && (deme.GetBirthCount() >= m_world->GetConfig().DEMES_REPLICATE_BIRTHS.Get())) ReplicateDeme(deme);
+ else if (m_world->GetConfig().DEMES_REPLICATE_ORGS.Get()
+ && (deme.GetOrgCount() >= m_world->GetConfig().DEMES_REPLICATE_ORGS.Get())) ReplicateDeme(deme);
}
// Print out all statistics about individual demes
@@ -2492,70 +2494,19 @@
//cerr << "Attempting to migrate with rate " << m_world->GetConfig().MIGRATION_RATE.Get() << "!" << endl;
int deme_id = parent_cell.GetDemeID();
+
+ //get another -unadjusted- deme id
+ int rnd_deme_id = m_world->GetRandom().GetInt(deme_array.GetSize()-1);
- //@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;
- }
+ //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 OTHER deme in neighborhood (assuming torus)
- //Extremely hacked, temporary until demes fixed
- else if (m_world->GetConfig().DEMES_MIGRATION_TARGET_MODE.Get() == 1) {
+ //set the new deme_id
+ deme_id = rnd_deme_id;
- //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);
-
- 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);
- }
-
- //@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();
- }
-
-
//The rest of this is essentially POSITION_CHILD_DEME_RANDOM
+ //@JEB: But note that this will not honor PREFER_EMPTY in the new deme.
const int deme_size = deme_array[deme_id].GetSize();
int out_pos = m_world->GetRandom().GetUInt(deme_size);
@@ -2569,26 +2520,29 @@
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...
- // @AWC If not migrating try out global/full-deme birth methods first...
- else if (birth_method == POSITION_CHILD_FULL_SOUP_RANDOM) {
+ // Similar to MIGRATION_RATE code above but allows for a bit more flexibility
+ // in how migration between demes works. Also, respects PREFER_EMPTY in new deme.
+ // Temporary until Deme
+ if ((m_world->GetConfig().DEMES_MIGRATION_RATE.Get() > 0.0)
+ && m_world->GetRandom().P(m_world->GetConfig().DEMES_MIGRATION_RATE.Get()))
+ {
+ deme_array[parent_cell.GetDemeID()].IncBirthCount();
+ return PositionDemeMigration(parent_cell, parent_ok);
+ }
+
+ // This block should be changed to a switch statment with functions handling
+ // the cases. For now, a bunch of if's that return if they handle.
+
+ if (birth_method == POSITION_CHILD_FULL_SOUP_RANDOM) {
- // @JEB Look randomly within empty cells, if requested
+ // Look randomly within empty cells first, if requested
if (m_world->GetConfig().PREFER_EMPTY.Get()) {
- // Note: empty_cell_id_array was resized to be large enough to hold
- // all cells in the cPopulation when it was created. Using functions
- // that resize it (like Push) will slow this code down considerably.
- // Instead, we keep track of how much of this memory we are using.
-
- int num_empty_cells = 0;
- for (int i=0; i<cell_array.GetSize(); i++) {
- if (GetCell(i).IsOccupied() == false) empty_cell_id_array[num_empty_cells++] = i;
- }
-
- if (num_empty_cells > 0) {
+ int num_empty_cells = UpdateEmptyCellIDArray();
+ if (num_empty_cells > 0) {
int out_pos = m_world->GetRandom().GetUInt(num_empty_cells);
return GetCell(empty_cell_id_array[out_pos]);
}
@@ -2600,7 +2554,8 @@
}
return GetCell(out_pos);
}
- else if (birth_method == POSITION_CHILD_FULL_SOUP_ELDEST) {
+
+ if (birth_method == POSITION_CHILD_FULL_SOUP_ELDEST) {
cPopulationCell * out_cell = reaper_queue.PopRear();
if (parent_ok == false && out_cell->GetID() == parent_cell.GetID()) {
out_cell = reaper_queue.PopRear();
@@ -2608,41 +2563,10 @@
}
return *out_cell;
}
- else if (birth_method == POSITION_CHILD_DEME_RANDOM) {
- const int deme_id = parent_cell.GetDemeID();
- const int deme_size = deme_array[deme_id].GetSize();
-
- deme_array[deme_id].IncBirthCount();
-
- // @JEB Look randomly within empty cells, if requested
- if (m_world->GetConfig().PREFER_EMPTY.Get()) {
-
- // Note: empty_cell_id_array was resized to be large enough to hold
- // all cells in the cPopulation when it was created. Using functions
- // that resize it (like Push) will slow this code down considerably.
- // Instead, we keep track of how much of this memory we are using.
-
- int num_empty_cells = 0;
- for (int i=0; i<deme_array[deme_id].GetSize(); i++) {
- int cell_id = deme_array[deme_id].GetCellID(i);
- if (!GetCell(cell_id).IsOccupied()) /*return cell;*/ empty_cell_id_array[num_empty_cells++] = cell_id;
- }
-
- if (num_empty_cells > 0) {
- int out_pos = m_world->GetRandom().GetUInt(num_empty_cells);
- return GetCell(empty_cell_id_array[out_pos]);
- }
- }
-
- 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);
- }
-
- return GetCell(out_cell_id);
+
+ if (birth_method == POSITION_CHILD_DEME_RANDOM) {
+ deme_array[parent_cell.GetDemeID()].IncBirthCount();
+ return PositionDemeRandom(parent_cell.GetDemeID(), parent_cell, parent_ok);
}
else if (birth_method == POSITION_CHILD_PARENT_FACING) {
return parent_cell.GetCellFaced();
@@ -2724,7 +2648,227 @@
return *( found_list.GetPos(choice) );
}
+void cPopulation::PositionAge(cPopulationCell & parent_cell,
+ tList<cPopulationCell> & found_list,
+ bool parent_ok)
+{
+ // Start with the parent organism as the replacement, and see if we can find
+ // anything equivilent or better.
+
+ found_list.Push(&parent_cell);
+ int max_age = parent_cell.GetOrganism()->GetPhenotype().GetAge();
+ if (parent_ok == false) max_age = -1;
+
+ // Now look at all of the neighbors.
+ tListIterator<cPopulationCell> conn_it( parent_cell.ConnectionList() );
+
+ cPopulationCell * test_cell;
+ while ( (test_cell = conn_it.Next()) != NULL) {
+ const int cur_age = test_cell->GetOrganism()->GetPhenotype().GetAge();
+ if (cur_age > max_age) {
+ max_age = cur_age;
+ found_list.Clear();
+ found_list.Push(test_cell);
+ }
+ else if (cur_age == max_age) {
+ found_list.Push(test_cell);
+ }
+ }
+}
+void cPopulation::PositionMerit(cPopulationCell & parent_cell,
+ tList<cPopulationCell> & found_list,
+ bool parent_ok)
+{
+ // Start with the parent organism as the replacement, and see if we can find
+ // anything equivilent or better.
+
+ found_list.Push(&parent_cell);
+ double max_ratio = parent_cell.GetOrganism()->CalcMeritRatio();
+ if (parent_ok == false) max_ratio = -1;
+
+ // Now look at all of the neighbors.
+ tListIterator<cPopulationCell> conn_it( parent_cell.ConnectionList() );
+
+ cPopulationCell * test_cell;
+ while ( (test_cell = conn_it.Next()) != NULL) {
+ const double cur_ratio = test_cell->GetOrganism()->CalcMeritRatio();
+ if (cur_ratio > max_ratio) {
+ max_ratio = cur_ratio;
+ found_list.Clear();
+ found_list.Push(test_cell);
+ }
+ else if (cur_ratio == max_ratio) {
+ found_list.Push(test_cell);
+ }
+ }
+}
+
+void cPopulation::PositionEnergyUsed(cPopulationCell & parent_cell,
+ tList<cPopulationCell> & found_list,
+ bool parent_ok)
+{
+ // Start with the parent organism as the replacement, and see if we can find
+ // anything equivilent or better.
+
+ found_list.Push(&parent_cell);
+ int max_energy_used = parent_cell.GetOrganism()->GetPhenotype().GetTimeUsed();
+ if (parent_ok == false) max_energy_used = -1;
+
+ // Now look at all of the neighbors.
+ tListIterator<cPopulationCell> conn_it( parent_cell.ConnectionList() );
+
+ cPopulationCell * test_cell;
+ while ( (test_cell = conn_it.Next()) != NULL) {
+ const int cur_energy_used = test_cell->GetOrganism()->GetPhenotype().GetTimeUsed();
+ if (cur_energy_used > max_energy_used) {
+ max_energy_used = cur_energy_used;
+ found_list.Clear();
+ found_list.Push(test_cell);
+ }
+ else if (cur_energy_used == max_energy_used) {
+ found_list.Push(test_cell);
+ }
+ }
+}
+
+// This function handles PositionChild() when there is migration between demes
+cPopulationCell& cPopulation::PositionDemeMigration(cPopulationCell& parent_cell, bool parent_ok)
+{
+ //cerr << "Attempting to migrate with rate " << m_world->GetConfig().MIGRATION_RATE.Get() << "!" << endl;
+ int deme_id = parent_cell.GetDemeID();
+
+ // Position randomly in any other deme
+ if (m_world->GetConfig().DEMES_MIGRATION_METHOD.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;
+ }
+
+ //Position randomly in an adjacent deme in neighborhood (assuming torus)
+ //Extremely hacked DEMES_NUM_X config setting simulates grid
+ else if (m_world->GetConfig().DEMES_MIGRATION_METHOD.Get() == 1) {
+
+ //get a random eight-neighbor
+ int dir = m_world->GetRandom().GetInt(8);
+
+ // 0 = NW, 1=N, continuing clockwise....
+
+ // Up one row
+ if (m_world->GetConfig().DEMES_NUM_X.Get() == 0) {
+ m_world->GetDriver().RaiseFatalException(1, "DEMES_NUM_X must be non-zero if DEMES_MIGRATION_METHOD 1 used.");
+ }
+ int x_size = m_world->GetConfig().DEMES_NUM_X.Get();
+ int y_size = (int) (m_world->GetConfig().NUM_DEMES.Get() / x_size);
+
+ 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);
+ }
+
+ //Random deme adjacent in list
+ else if (m_world->GetConfig().DEMES_MIGRATION_METHOD.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 + GetNumDemes()) % GetNumDemes();
+ }
+
+ // TODO the above choice of deme does not respect PREFER_EMPTY
+ // i.e., it does not preferentially pick a deme with empty cells if they are
+ // it might make sense for that to happen...
+
+ // Now return an empty cell from the chosen deme
+ return PositionDemeRandom(deme_id, parent_cell, parent_ok);
+}
+
+// This function handles PositionChild() by returning a random cell from the entire deme.
+cPopulationCell& cPopulation::PositionDemeRandom(int deme_id, cPopulationCell& parent_cell, bool parent_ok)
+{
+ assert((deme_id >=0) && (deme_id < deme_array.GetSize()));
+
+ const int deme_size = deme_array[deme_id].GetSize();
+ cDeme& deme = deme_array[deme_id];
+
+ // Look randomly within empty cells first, if requested
+ if (m_world->GetConfig().PREFER_EMPTY.Get()) {
+
+ int num_empty_cells = UpdateEmptyCellIDArray(deme_id);
+ if (num_empty_cells > 0) {
+ int out_pos = m_world->GetRandom().GetUInt(num_empty_cells);
+ return GetCell(empty_cell_id_array[out_pos]);
+ }
+ }
+
+ int out_pos = m_world->GetRandom().GetUInt(deme_size);
+ int out_cell_id = deme.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.GetCellID(out_pos);
+ }
+
+ return GetCell(out_cell_id);
+}
+
+
+// This function updates the list of empty cell ids in the population
+// and returns the number of empty cells found. Used by global PREFER_EMPTY
+// PositionChild() methods. If deme_id is -1 (the default), then operates
+// on the entire population.
+int cPopulation::UpdateEmptyCellIDArray(int deme_id)
+{
+ int num_empty_cells = 0;
+ cDeme& deme = deme_array[deme_id];
+ // Note: empty_cell_id_array was resized to be large enough to hold
+ // all cells in the cPopulation when it was created. Using functions
+ // that resize it (like Push) will slow this code down considerably.
+ // Instead, we keep track of how much of this memory we are using.
+
+ // Look at all cells
+ if (deme_id == -1) {
+ for (int i=0; i<cell_array.GetSize(); i++) {
+ if (GetCell(i).IsOccupied() == false) empty_cell_id_array[num_empty_cells++] = i;
+ }
+ }
+ // Look at a specific deme
+ else {
+ for (int i=0; i<deme.GetSize(); i++) {
+ if (GetCell(deme.GetCellID(i)).IsOccupied() == false) empty_cell_id_array[num_empty_cells++] = deme.GetCellID(i);
+ }
+ }
+
+ return num_empty_cells;
+}
+
+
int cPopulation::ScheduleOrganism()
{
return schedule->GetNextID();
@@ -2813,6 +2957,10 @@
// Loop through all the demes getting stats and doing calculations
// which must be done on a deme by deme basis.
void cPopulation::UpdateDemeStats() {
+
+ // bail early to save time if there are no demes
+ if (GetNumDemes() == 1) return ;
+
cStats& stats = m_world->GetStats();
stats.SumDemeAge().Clear();
@@ -2823,11 +2971,13 @@
stats.SumDemeGestationTime().Clear();
stats.SumDemeNormalizedTimeUsed().Clear();
stats.SumDemeMerit().Clear();
-
+
for(int i = 0; i < GetNumDemes(); i++) {
cDeme& deme = GetDeme(i);
- if(deme.IsEmpty()) // ignore empty demes
+ if(!deme.IsEmpty()) // ignore empty demes
+ {
continue;
+ }
stats.SumDemeAge().Add(deme.GetAge());
stats.SumDemeBirthCount().Add(deme.GetBirthCount());
stats.SumDemeOrgCount().Add(deme.GetOrgCount());
@@ -3583,90 +3733,6 @@
}
-void cPopulation::PositionAge(cPopulationCell & parent_cell,
- tList<cPopulationCell> & found_list,
- bool parent_ok)
-{
- // Start with the parent organism as the replacement, and see if we can find
- // anything equivilent or better.
-
- found_list.Push(&parent_cell);
- int max_age = parent_cell.GetOrganism()->GetPhenotype().GetAge();
- if (parent_ok == false) max_age = -1;
-
- // Now look at all of the neighbors.
- tListIterator<cPopulationCell> conn_it( parent_cell.ConnectionList() );
-
- cPopulationCell * test_cell;
- while ( (test_cell = conn_it.Next()) != NULL) {
- const int cur_age = test_cell->GetOrganism()->GetPhenotype().GetAge();
- if (cur_age > max_age) {
- max_age = cur_age;
- found_list.Clear();
- found_list.Push(test_cell);
- }
- else if (cur_age == max_age) {
- found_list.Push(test_cell);
- }
- }
-}
-
-void cPopulation::PositionMerit(cPopulationCell & parent_cell,
- tList<cPopulationCell> & found_list,
- bool parent_ok)
-{
- // Start with the parent organism as the replacement, and see if we can find
- // anything equivilent or better.
-
- found_list.Push(&parent_cell);
- double max_ratio = parent_cell.GetOrganism()->CalcMeritRatio();
- if (parent_ok == false) max_ratio = -1;
-
- // Now look at all of the neighbors.
- tListIterator<cPopulationCell> conn_it( parent_cell.ConnectionList() );
-
- cPopulationCell * test_cell;
- while ( (test_cell = conn_it.Next()) != NULL) {
- const double cur_ratio = test_cell->GetOrganism()->CalcMeritRatio();
- if (cur_ratio > max_ratio) {
- max_ratio = cur_ratio;
- found_list.Clear();
- found_list.Push(test_cell);
- }
- else if (cur_ratio == max_ratio) {
- found_list.Push(test_cell);
- }
- }
-}
-
-void cPopulation::PositionEnergyUsed(cPopulationCell & parent_cell,
- tList<cPopulationCell> & found_list,
- bool parent_ok)
-{
- // Start with the parent organism as the replacement, and see if we can find
- // anything equivilent or better.
-
- found_list.Push(&parent_cell);
- int max_energy_used = parent_cell.GetOrganism()->GetPhenotype().GetTimeUsed();
- if (parent_ok == false) max_energy_used = -1;
-
- // Now look at all of the neighbors.
- tListIterator<cPopulationCell> conn_it( parent_cell.ConnectionList() );
-
- cPopulationCell * test_cell;
- while ( (test_cell = conn_it.Next()) != NULL) {
- const int cur_energy_used = test_cell->GetOrganism()->GetPhenotype().GetTimeUsed();
- if (cur_energy_used > max_energy_used) {
- max_energy_used = cur_energy_used;
- found_list.Clear();
- found_list.Push(test_cell);
- }
- else if (cur_energy_used == max_energy_used) {
- found_list.Push(test_cell);
- }
- }
-}
-
void cPopulation::FindEmptyCell(tList<cPopulationCell> & cell_list,
tList<cPopulationCell> & found_list)
{
Modified: development/source/main/cPopulation.h
===================================================================
--- development/source/main/cPopulation.h 2008-04-01 20:20:46 UTC (rev 2511)
+++ development/source/main/cPopulation.h 2008-04-01 20:45:48 UTC (rev 2512)
@@ -120,6 +120,9 @@
void PositionAge(cPopulationCell& parent_cell, tList<cPopulationCell>& found_list, bool parent_ok);
void PositionMerit(cPopulationCell & parent_cell, tList<cPopulationCell>& found_list, bool parent_ok);
void PositionEnergyUsed(cPopulationCell & parent_cell, tList<cPopulationCell>& found_list, bool parent_ok);
+ cPopulationCell& PositionDemeMigration(cPopulationCell& parent_cell, bool parent_ok = true);
+ cPopulationCell& PositionDemeRandom(int deme_id, cPopulationCell& parent_cell, bool parent_ok = true);
+ int UpdateEmptyCellIDArray(int deme_id = -1);
void FindEmptyCell(tList<cPopulationCell>& cell_list, tList<cPopulationCell>& found_list);
// Update statistics collecting...
Modified: development/source/main/cStats.cc
===================================================================
--- development/source/main/cStats.cc 2008-04-01 20:20:46 UTC (rev 2511)
+++ development/source/main/cStats.cc 2008-04-01 20:45:48 UTC (rev 2512)
@@ -1327,3 +1327,63 @@
}
m_deme_founders.clear();
}
+
+void cStats::PrintDemeTasks(const cString& filename){
+ cDataFile& df = m_world->GetDataFile(filename);
+ df.WriteComment("Avida deme tasks data");
+ df.WriteTimeStamp();
+ df.WriteComment("First column gives the current update, next columns give the number");
+ df.WriteComment("of organisms that have the particular task as a component of their merit");
+ df.WriteComment("in a particular deme");
+
+ const int num_tasks = m_world->GetEnvironment().GetNumTasks();
+
+ df.Write(m_update, "Update");
+ for(int i=0; i<m_world->GetPopulation().GetNumDemes(); ++i) {
+ cDeme& deme = m_world->GetPopulation().GetDeme(i);
+ for(int j = 0; j < num_tasks; j++) {
+ df.Write( (deme.GetLastTaskCount()[j] > 0), cStringUtil::Stringf("%i.", i) + task_names[j] );
+ }
+ }
+ df.Endl();
+}
+
+void cStats::PrintDemeTasksExe(const cString& filename){
+ cDataFile& df = m_world->GetDataFile(filename);
+ df.WriteComment("Avida deme tasks exe data");
+ df.WriteTimeStamp();
+ df.WriteComment("First column gives the current update, next columns give the number");
+ df.WriteComment("of times a task has contributed to the merit of all organisms");
+ df.WriteComment("in a particular deme");
+
+ const int num_tasks = m_world->GetEnvironment().GetNumTasks();
+
+ df.Write(m_update, "Update");
+ for(int i=0; i<m_world->GetPopulation().GetNumDemes(); ++i) {
+ cDeme& deme = m_world->GetPopulation().GetDeme(i);
+ for(int j = 0; j < num_tasks; j++) {
+ df.Write( deme.GetLastTaskCount()[j], cStringUtil::Stringf("%i.", i) + task_names[j] );
+ }
+ }
+ df.Endl();
+}
+
+void cStats::PrintDemeReactions(const cString& filename){
+ cDataFile& df = m_world->GetDataFile(filename);
+ df.WriteComment("Avida deme reactions data");
+ df.WriteTimeStamp();
+ df.WriteComment("First column gives the current update, all further columns give the number");
+ df.WriteComment("of currently living organisms each reaction has affected.");
+
+ const int num_reactions = m_world->GetEnvironment().GetReactionLib().GetSize();
+
+ df.Write(m_update, "Update");
+ for(int i=0; i<m_world->GetPopulation().GetNumDemes(); ++i) {
+ cDeme& deme = m_world->GetPopulation().GetDeme(i);
+ for(int j = 0; j < num_reactions; j++) {
+ df.Write( deme.GetLastReactionCount()[j], cStringUtil::Stringf("%i.", i) + m_world->GetEnvironment().GetReactionLib().GetReaction(j)->GetName() );
+ }
+ }
+ df.Endl();
+}
+
Modified: development/source/main/cStats.h
===================================================================
--- development/source/main/cStats.h 2008-04-01 20:20:46 UTC (rev 2511)
+++ development/source/main/cStats.h 2008-04-01 20:45:48 UTC (rev 2512)
@@ -418,7 +418,7 @@
cIntSum& SumDemeGestationTime() { return sum_deme_gestation_time; }
cDoubleSum& SumDemeNormalizedTimeUsed() { return sum_deme_normalized_time_used; }
cDoubleSum& SumDemeMerit() { return sum_deme_merit; }
-
+
#if INSTRUCTION_COUNT
void ZeroInst();
#endif
@@ -719,6 +719,11 @@
//! Print the genotype IDs for the founders of demes that have recently been "born."
void PrintDemeFounders(const cString& filename);
+ void PrintDemeTasks(const cString& filename);
+ void PrintDemeTasksExe(const cString& filename);
+ void PrintDemeReactions(const cString& filename);
+
+
protected:
int m_deme_num_repls; //!< Number of deme replications since last PrintDemeReplicationData.
cDoubleSum m_deme_gestation_time; //!< Gestation time for demes - mean age at deme replication.
More information about the Avida-cvs
mailing list