[Avida-SVN] r1080 - in development/source: actions main tools
ofria at myxo.css.msu.edu
ofria at myxo.css.msu.edu
Sun Nov 12 16:00:13 PST 2006
Author: ofria
Date: 2006-11-12 19:00:13 -0500 (Sun, 12 Nov 2006)
New Revision: 1080
Modified:
development/source/actions/EnvironmentActions.cc
development/source/actions/PopulationActions.cc
development/source/main/cEnvironment.cc
development/source/main/cEnvironment.h
development/source/main/cPopulation.cc
development/source/main/cPopulation.h
development/source/tools/cString.h
Log:
Added divide_demes action that will divide up the organisms in a deme (across
this and another random deme) when a given condition is met.
Modified the set_reaction_value event to take special names "ALL" to affect
all reactions and "RANDOM:3" (to affect random reactions, 3 in this case).
Modified: development/source/actions/EnvironmentActions.cc
===================================================================
--- development/source/actions/EnvironmentActions.cc 2006-11-11 17:44:00 UTC (rev 1079)
+++ development/source/actions/EnvironmentActions.cc 2006-11-13 00:00:13 UTC (rev 1080)
@@ -134,6 +134,11 @@
};
+// Set the values associated with a specified reaction. If the name of the
+// reaction used is "ALL" then all reactions will be changed. If the name is
+// "RANDOM:3" then random reactions will be set to the specified value. The
+// number after the colon indicated the number of reactions to set.
+
class cActionSetReactionValue : public cAction
{
private:
@@ -152,7 +157,7 @@
void Process(cAvidaContext& ctx)
{
- m_world->GetEnvironment().SetReactionValue(m_name, m_value);
+ m_world->GetEnvironment().SetReactionValue(ctx, m_name, m_value);
}
};
Modified: development/source/actions/PopulationActions.cc
===================================================================
--- development/source/actions/PopulationActions.cc 2006-11-11 17:44:00 UTC (rev 1079)
+++ development/source/actions/PopulationActions.cc 2006-11-13 00:00:13 UTC (rev 1080)
@@ -118,11 +118,9 @@
Parameters:
filename (string)
- The filename of the genotype to load. If this is left empty, or the keyword
- "START_CREATURE" is given, than the genotype specified in the genesis
+ The filename of the genotype to load. If empty (or the keyword
+ "START_CREATURE" is given) than the genotype specified in the genesis
file under "START_CREATURE" is used.
- cell ID (integer) default: 0
- The grid-point into which the organism should be placed.
merit (double) default: -1
The initial merit of the organism. If set to -1, this is ignored.
lineage label (integer) default: 0
@@ -862,6 +860,42 @@
/*
+ This action will determine if any demes have filled up, and if so move half
+ of the members into a new deme. Specifically, it will leave the even
+ numbered cells (0,2,4, etc.) and take the odd numbered ones (1,3,5, etc.)
+
+ @CAO This next part should be configurable
+ All replicated organisms will have their merit recalculated given the full
+ list of completed tasks, and assigned to all offspring *and* all parents.
+
+ This action should be used in combination with:
+ BIRTH_METHOD 8 (always repoduce into id+1)
+ BASE_MERIT_METHOD 0 (Constant base merit)
+ BASE_CONST_MERIT 0 (Use a base merit of zero, hence all merits = 0)
+
+ These settings will make sure that all merit will be set by this action.
+*/
+
+class cActionDivideDemes : public cAction
+{
+private:
+public:
+ cActionDivideDemes(cWorld* world, const cString& args) : cAction(world, args)
+ {
+ cString largs(args);
+ // Nothing to do here yet....
+ }
+
+ static const cString GetDescription() { return "No arguments (yet!)"; }
+
+ void Process(cAvidaContext& ctx)
+ {
+ m_world->GetPopulation().DivideDemes();
+ }
+};
+
+
+/*
Designed to serve as a control for the compete_demes. Each deme is
copied into itself and the parameters reset.
*/
@@ -1254,6 +1288,7 @@
action_lib->Register<cActionCompeteDemes>("CompeteDemes");
action_lib->Register<cActionReplicateDemes>("ReplicateDemes");
+ action_lib->Register<cActionDivideDemes>("DivideDemes");
action_lib->Register<cActionResetDemes>("ResetDemes");
action_lib->Register<cActionCopyDeme>("CopyDeme");
Modified: development/source/main/cEnvironment.cc
===================================================================
--- development/source/main/cEnvironment.cc 2006-11-11 17:44:00 UTC (rev 1079)
+++ development/source/main/cEnvironment.cc 2006-11-13 00:00:13 UTC (rev 1080)
@@ -838,8 +838,41 @@
return found_reaction->GetValue();
}
-bool cEnvironment::SetReactionValue(const cString& name, double value)
+bool cEnvironment::SetReactionValue(cAvidaContext& ctx, const cString& name, double value)
{
+ const int num_reactions = reaction_lib.GetSize();
+
+ // See if this should be applied to all reactions.
+ if (name == "ALL") {
+ // Loop through all reactions to update their values.
+ for (int i = 0; i < num_reactions; i++) {
+ cReaction* cur_reaction = reaction_lib.GetReaction(i);
+ assert(cur_reaction != NULL);
+ cur_reaction->ModifyValue(value);
+ }
+
+ return true;
+ }
+
+ // See if this should be applied to random reactions.
+ if (name.IsSubstring("RANDOM:", 0)) {
+ // Determine how many reactions to set.
+ const int num_set = name.Substring(7, name.GetSize()-7).AsInt();
+ if (num_set > num_reactions) return false;
+
+ // Choose the reactions.
+ tArray<int> reaction_ids(num_set);
+ ctx.GetRandom().Choose(num_reactions, reaction_ids);
+
+ // And set them...
+ for (int i = 0; i < num_set; i++) {
+ cReaction* cur_reaction = reaction_lib.GetReaction(reaction_ids[i]);
+ assert(cur_reaction != NULL);
+ cur_reaction->ModifyValue(value);
+ }
+ return true;
+ }
+
cReaction* found_reaction = reaction_lib.GetReaction(name);
if (found_reaction == NULL) return false;
found_reaction->ModifyValue(value);
Modified: development/source/main/cEnvironment.h
===================================================================
--- development/source/main/cEnvironment.h 2006-11-11 17:44:00 UTC (rev 1079)
+++ development/source/main/cEnvironment.h 2006-11-13 00:00:13 UTC (rev 1080)
@@ -110,7 +110,7 @@
cMutationRates& GetMutRates() { return mut_rates; }
double GetReactionValue(int& reaction_id);
- bool SetReactionValue(const cString& name, double value);
+ bool SetReactionValue(cAvidaContext& ctx, const cString& name, double value);
bool SetReactionValueMult(const cString& name, double value_mult);
bool SetReactionInst(const cString& name, cString inst_name);
};
Modified: development/source/main/cPopulation.cc
===================================================================
--- development/source/main/cPopulation.cc 2006-11-11 17:44:00 UTC (rev 1079)
+++ development/source/main/cPopulation.cc 2006-11-13 00:00:13 UTC (rev 1080)
@@ -860,6 +860,7 @@
{
// Determine which demes should be replicated.
const int num_demes = GetNumDemes();
+ cRandom & random = m_world->GetRandom();
// Loop through all candidate demes...
for (int deme_id = 0; deme_id < num_demes; deme_id++) {
@@ -892,8 +893,6 @@
// -- If we made it this far, we should replicate this deme --
- cRandom & random = m_world->GetRandom();
-
// Choose a random organism from this deme...
int cell1_id = -1;
const int deme1_size = source_deme.GetSize();
@@ -905,7 +904,7 @@
int target_id = deme_id;
while (target_id == deme_id) target_id = random.GetUInt(num_demes);
cDeme & target_deme = deme_array[target_id];
-
+
// Clear out existing cells in target deme.
const int deme2_size = target_deme.GetSize();
for (int i = 0; i < deme2_size; i++) {
@@ -934,6 +933,74 @@
}
+// Loop through all demes to determine if any are ready to be divided. All
+// full demes have 1/2 of their organisms (the odd ones) moved into a new deme.
+
+void cPopulation::DivideDemes()
+{
+ // Determine which demes should be replicated.
+ const int num_demes = GetNumDemes();
+ cRandom & random = m_world->GetRandom();
+
+ // Loop through all candidate demes...
+ for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+ cDeme & source_deme = deme_array[deme_id];
+
+ // Only divide full demes.
+ if (source_deme.IsFull() == false) continue;
+
+ // Choose a random target deme to replicate to...
+ int target_id = deme_id;
+ while (target_id == deme_id) target_id = random.GetUInt(num_demes);
+ cDeme & target_deme = deme_array[target_id];
+ const int deme_size = target_deme.GetSize();
+
+ // Clear out existing cells in target deme.
+ for (int i = 0; i < deme_size; i++) {
+ KillOrganism(cell_array[ target_deme.GetCellID(i) ]);
+ }
+
+ // Setup an array to collect the total number of tasks performed.
+ const int num_tasks = cell_array[source_deme.GetCellID(0)].GetOrganism()->
+ GetPhenotype().GetLastTaskCount().GetSize();
+ tArray<int> tot_tasks(num_tasks);
+ tot_tasks.SetAll(0);
+
+ // Move over the odd numbered cells.
+ for (int pos = 0; pos < deme_size; pos += 2) {
+ const int cell1_id = source_deme.GetCellID( pos+1 );
+ const int cell2_id = target_deme.GetCellID( pos );
+ cOrganism * org1 = cell_array[cell1_id].GetOrganism();
+
+ // Keep track of what tasks have been done.
+ const tArray<int> & cur_tasks = org1->GetPhenotype().GetLastTaskCount();
+ for (int i = 0; i < num_tasks; i++) {
+ tot_tasks[i] += cur_tasks[i];
+ }
+
+ // Inject a copy of the odd organisms into the even cells.
+ InjectClone( cell2_id, *org1 );
+
+ // Kill the organisms in the odd cells.
+ KillOrganism( cell_array[cell1_id] );
+ }
+
+ // Figure out the merit each organism should have.
+ int merit = 100;
+ for (int i = 0; i < num_tasks; i++) {
+ if (tot_tasks[i] > 0) merit *= 2;
+ }
+
+ // Setup the merit of both old and new individuals.
+ for (int pos = 0; pos < deme_size; pos += 2) {
+ cell_array[source_deme.GetCellID(pos)].GetOrganism()->UpdateMerit(merit);
+ cell_array[target_deme.GetCellID(pos)].GetOrganism()->UpdateMerit(merit);
+ }
+
+ }
+}
+
+
// Reset Demes goes through each deme and resets the individual organisms as
// if they were just injected into the population.
Modified: development/source/main/cPopulation.h
===================================================================
--- development/source/main/cPopulation.h 2006-11-11 17:44:00 UTC (rev 1079)
+++ development/source/main/cPopulation.h 2006-11-13 00:00:13 UTC (rev 1080)
@@ -138,6 +138,7 @@
// Deme-related methods
void CompeteDemes(int competition_type);
void ReplicateDemes(int rep_trigger);
+ void DivideDemes();
void ResetDemes();
void CopyDeme(int deme1_id, int deme2_id);
void SpawnDeme(int deme1_id, int deme2_id=-1);
Modified: development/source/tools/cString.h
===================================================================
--- development/source/tools/cString.h 2006-11-11 17:44:00 UTC (rev 1079)
+++ development/source/tools/cString.h 2006-11-13 00:00:13 UTC (rev 1080)
@@ -523,6 +523,13 @@
**/
cString Substring(int start, int size) const ;
+ /**
+ * Determine if in_string is a substring of this string.
+ *
+ * @return Is this a substring?
+ * @param in_string the string to test.
+ * @param start The beginning of the substring in the string.
+ **/
bool IsSubstring(const cString & in_string, int start) const;
/*
More information about the Avida-cvs
mailing list