[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