[Avida-SVN] r1100 - in development/source: . cpu main

barrick at myxo.css.msu.edu barrick at myxo.css.msu.edu
Sat Nov 25 13:06:38 PST 2006


Author: barrick
Date: 2006-11-25 16:06:30 -0500 (Sat, 25 Nov 2006)
New Revision: 1100

Modified:
   development/source/cpu/cHardwareCPU.cc
   development/source/cpu/cHardwareCPU.h
   development/source/cpu/cHardwareManager.cc
   development/source/defs.h
   development/source/main/cAvidaConfig.h
   development/source/main/cInstSet.cc
   development/source/main/cInstSet.h
   development/source/main/cPhenotype.h
   development/source/main/cPopulation.cc
Log:
Added a new birth method: replace the organism with the largest time used in the entire soup.

Added a column to instruction set files that modifies how much an instruction contributes to the time used. This allows instructions to take the same real time, but contribute differently to gestation time. I'm using it to make flow control instructions much cheaper than instructions required to complete tasks.

Modified sense instruction so that there are now two flavors for converting an absolute resource amount double into an integer: (1) Log2 (2) Mult by 100.  Change is backwards compatible.



Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc	2006-11-24 20:50:30 UTC (rev 1099)
+++ development/source/cpu/cHardwareCPU.cc	2006-11-25 21:06:30 UTC (rev 1100)
@@ -224,7 +224,8 @@
     cInstEntryCPU("buy", &cHardwareCPU::Inst_Buy),
     cInstEntryCPU("send",      &cHardwareCPU::Inst_Send),
     cInstEntryCPU("receive",   &cHardwareCPU::Inst_Receive),
-    cInstEntryCPU("sense",     &cHardwareCPU::Inst_Sense),
+    cInstEntryCPU("sense",     &cHardwareCPU::Inst_SenseLog2),
+    cInstEntryCPU("sense-m100",     &cHardwareCPU::Inst_SenseMult100),
     
     cInstEntryCPU("donate-rnd",  &cHardwareCPU::Inst_DonateRandom),
     cInstEntryCPU("donate-kin",  &cHardwareCPU::Inst_DonateKin),
@@ -435,7 +436,7 @@
     inst_cost[i] = m_inst_set->GetCost(cInstruction(i));
     inst_ft_cost[i] = m_inst_set->GetFTCost(cInstruction(i));
   }
-#endif
+#endif 
   
 }
 
@@ -505,9 +506,13 @@
     if (exec == true) {
       SingleProcess_ExecuteInst(ctx, cur_inst);
       
-      // Some instruction (such as jump) may turn m_advance_ip off.  Ususally
+      // Some instruction (such as jump) may turn m_advance_ip off.  Usually
       // we now want to move to the next instruction in the memory.
       if (m_advance_ip == true) IP().Advance();
+      
+      // Pay the additional death_cost of the instruction now
+      phenotype.IncTimeUsed(m_inst_set->GetAddlTimeCost(cur_inst));
+      
     } // if exec
     
   } // Previous was executed once for each thread...
@@ -2476,6 +2481,10 @@
 
 bool cHardwareCPU::Inst_Repro(cAvidaContext& ctx)
 {
+  // const bool viable = Divide_CheckViable(ctx, div_point, child_size);
+  // these checks should be done, but currently they make some assumptions
+  // that crash when evaluating this kind of organism -- JEB
+
   // Setup child
   cCPUMemory& child_genome = organism->ChildGenome();
   child_genome = GetMemory();
@@ -2521,6 +2530,9 @@
   
   organism->ActivateDivide(ctx);
   
+  //Reset the parent
+  if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) Reset();
+
   return true;
 }
 
@@ -2714,7 +2726,10 @@
   const int value = GetRegister(reg_used);
   GetRegister(reg_used) = 0;
   organism->DoOutput(ctx, value);
-  organism->GetPhenotype().SetCurBonus(organism->GetPhenotype().GetCurBonus() * 0.5);
+  double new_bonus = organism->GetPhenotype().GetCurBonus();
+  new_bonus *= 0.5;
+//if (new_bonus < 1) new_bonus = 1;
+  organism->GetPhenotype().SetCurBonus(new_bonus);
   return true;
 }
 
@@ -2838,11 +2853,20 @@
   return true;
 }
 
-bool cHardwareCPU::Inst_Sense(cAvidaContext& ctx)
+bool cHardwareCPU::Inst_SenseLog2(cAvidaContext& ctx)
 {
+  return DoSense(ctx, 0, 2);
+}
+
+bool cHardwareCPU::Inst_SenseMult100(cAvidaContext& ctx)
+{
+  return DoSense(ctx, 1, 100);
+}
+
+bool cHardwareCPU::DoSense(cAvidaContext& ctx, int conversion_method, double base)
+{
   // Returns the log2 amount of a resource or resources 
   // specified by modifying NOPs into register BX
-
   const tArray<double> & res_count = organism->GetOrgInterface().GetResources();
 
   // Arbitrarily set to BX since the conditionals use this directly.
@@ -2858,7 +2882,7 @@
   
   if ((last_num_resources != res_count.GetSize()))
   {
-      max_label_length = (int)ceil(log((double)res_count.GetSize())/log((double)num_nops));
+      max_label_length = (int) ceil(log((double)res_count.GetSize())/log((double)num_nops));
       last_num_resources = res_count.GetSize();
   }
 
@@ -2902,11 +2926,22 @@
   int resource_result = 0;
   for (int i = start_index; i <= end_index; i++)
   {
-    // if it's a valid resource and not zero
-    // (alternately you could assign min_int for zero resources, but
-    // that would cause wierdness when adding sense values together)
-    if ((i < res_count.GetSize()) && (res_count[i] > 0)) resource_result += (int)(log(res_count[i])/0.69314718056);
-    // 0.69314718056 is log (2)
+    // if it's a valid resource
+    if (i < res_count.GetSize())
+    {
+      if (conversion_method == 0) // Log2
+      {
+        // (alternately you could assign min_int for zero resources, but
+        // that would cause wierdness when adding sense values together)
+        if (res_count[i] > 0) resource_result += (int)(log(res_count[i])/log(base));
+      }
+      else if (conversion_method == 1) // Addition of multiplied resource amount
+      {
+        int add_amount = (int) (res_count[i] * base);
+        // Do some range checking to make sure we don't overflow
+        resource_result = (INT_MAX - resource_result <= add_amount) ? INT_MAX : resource_result + add_amount;
+      }
+    } 
   }
     
   //Dump this value into an arbitrary register: BX

Modified: development/source/cpu/cHardwareCPU.h
===================================================================
--- development/source/cpu/cHardwareCPU.h	2006-11-24 20:50:30 UTC (rev 1099)
+++ development/source/cpu/cHardwareCPU.h	2006-11-25 21:06:30 UTC (rev 1100)
@@ -392,7 +392,9 @@
   bool Inst_Buy(cAvidaContext& ctx);
   bool Inst_Send(cAvidaContext& ctx);
   bool Inst_Receive(cAvidaContext& ctx);
-  bool Inst_Sense(cAvidaContext& ctx);
+  bool Inst_SenseLog2(cAvidaContext& ctx);
+  bool Inst_SenseMult100(cAvidaContext& ctx);
+  bool DoSense(cAvidaContext& ctx, int conversion_method, double base);
 
   void DoDonate(cOrganism * to_org);
   bool Inst_DonateRandom(cAvidaContext& ctx);

Modified: development/source/cpu/cHardwareManager.cc
===================================================================
--- development/source/cpu/cHardwareManager.cc	2006-11-24 20:50:30 UTC (rev 1099)
+++ development/source/cpu/cHardwareManager.cc	2006-11-25 21:06:30 UTC (rev 1100)
@@ -76,7 +76,8 @@
     int cost = cur_line.PopWord().AsInt();
     int ft_cost = cur_line.PopWord().AsInt();
     double prob_fail = cur_line.PopWord().AsDouble();
-    
+    int addl_time_cost = cur_line.PopWord().AsInt();
+
     // If this instruction has 0 redundancy, we don't want it!
     if (redundancy < 0) continue;
     if (redundancy > 256) {
@@ -90,14 +91,14 @@
     // First, determine if it is a nop...
     int nop_mod = -1;
     if(nop_dict.Find(inst_name, nop_mod) == true) {
-      m_inst_set.AddNop(nop_mod, redundancy, ft_cost, cost, prob_fail);
+      m_inst_set.AddNop(nop_mod, redundancy, ft_cost, cost, prob_fail, addl_time_cost);
       continue;
     }
     
     // Otherwise, it had better be in the main dictionary...
     int fun_id = -1;
     if(inst_dict.Find(inst_name, fun_id) == true){
-      m_inst_set.AddInst(fun_id, redundancy, ft_cost, cost, prob_fail);
+      m_inst_set.AddInst(fun_id, redundancy, ft_cost, cost, prob_fail, addl_time_cost);
       continue;
     }
     

Modified: development/source/defs.h
===================================================================
--- development/source/defs.h	2006-11-24 20:50:30 UTC (rev 1099)
+++ development/source/defs.h	2006-11-25 21:06:30 UTC (rev 1100)
@@ -131,7 +131,8 @@
   POSITION_CHILD_FULL_SOUP_ELDEST,
   POSITION_CHILD_DEME_RANDOM,
   POSITION_CHILD_PARENT_FACING,
-  POSITION_CHILD_NEXT_CELL
+  POSITION_CHILD_NEXT_CELL,
+  POSITION_CHILD_FULL_SOUP_TIME_USED
 };
 const int NUM_LOCAL_POSITION_CHILD = POSITION_CHILD_FULL_SOUP_RANDOM;
 

Modified: development/source/main/cAvidaConfig.h
===================================================================
--- development/source/main/cAvidaConfig.h	2006-11-24 20:50:30 UTC (rev 1099)
+++ development/source/main/cAvidaConfig.h	2006-11-25 21:06:30 UTC (rev 1100)
@@ -181,7 +181,7 @@
   CONFIG_ADD_VAR(START_CREATURE, cString, "default-classic.org", "Organism to seed the soup");
   
   CONFIG_ADD_GROUP(REPRODUCTION_GROUP, "Birth and Death");
-  CONFIG_ADD_VAR(BIRTH_METHOD, int, 0, "Which organism should be replaced on birth?\n0 = Random organism in neighborhood\n1 = Oldest in neighborhood\n2 = Largest Age/Merit in neighborhood\n3 = None (use only empty cells in neighborhood)\n4 = Random from population (Mass Action)\n5 = Oldest in entire population\n6 = Random within deme\n7 = Organism faced by parent\n8 = Next grid cell (id+1)");
+  CONFIG_ADD_VAR(BIRTH_METHOD, int, 0, "Which organism should be replaced on birth?\n0 = Random organism in neighborhood\n1 = Oldest in neighborhood\n2 = Largest Age/Merit in neighborhood\n3 = None (use only empty cells in neighborhood)\n4 = Random from population (Mass Action)\n5 = Oldest in entire population\n6 = Random within deme\n7 = Organism faced by parent\n8 = Next grid cell (id+1)\n9= Max time used in entire population");
   CONFIG_ADD_VAR(PREFER_EMPTY, int, 1, "Give empty cells preference in offsping placement?");
   CONFIG_ADD_VAR(DEATH_METHOD, int, 2, "0 = Never die of old age.\n1 = Die when inst executed = AGE_LIMIT (+deviation)\n2 = Die when inst executed = length*AGE_LIMIT (+dev)");
   CONFIG_ADD_VAR(AGE_LIMIT, int, 20, "Modifies DEATH_METHOD");

Modified: development/source/main/cInstSet.cc
===================================================================
--- development/source/main/cInstSet.cc	2006-11-24 20:50:30 UTC (rev 1099)
+++ development/source/main/cInstSet.cc	2006-11-25 21:06:30 UTC (rev 1100)
@@ -49,7 +49,7 @@
   return cInstruction(inst_op);
 }
 
-int cInstSet::AddInst(int lib_fun_id, int redundancy, int ft_cost, int cost, double prob_fail)
+int cInstSet::AddInst(int lib_fun_id, int redundancy, int ft_cost, int cost, double prob_fail, int addl_time_cost)
 {
   const int inst_id = m_lib_name_map.GetSize();
 
@@ -64,6 +64,7 @@
   m_lib_name_map[inst_id].cost = cost;
   m_lib_name_map[inst_id].ft_cost = ft_cost;
   m_lib_name_map[inst_id].prob_fail = prob_fail;
+  m_lib_name_map[inst_id].addl_time_cost = addl_time_cost;
 
   const int total_redundancy = m_mutation_chart.GetSize();
   m_mutation_chart.Resize(total_redundancy + redundancy);
@@ -74,12 +75,12 @@
   return inst_id;
 }
 
-int cInstSet::AddNop(int lib_nopmod_id, int redundancy, int ft_cost, int cost, double prob_fail)
+int cInstSet::AddNop(int lib_nopmod_id, int redundancy, int ft_cost, int cost, double prob_fail, int addl_time_cost)
 {
   // Assert nops are at the _beginning_ of an inst_set.
   assert(m_lib_name_map.GetSize() == m_lib_nopmod_map.GetSize());
 
-  const int inst_id = AddInst(lib_nopmod_id, redundancy, ft_cost, cost, prob_fail);
+  const int inst_id = AddInst(lib_nopmod_id, redundancy, ft_cost, cost, prob_fail, addl_time_cost);
 
   m_lib_nopmod_map.Resize(inst_id + 1);
   m_lib_nopmod_map[inst_id] = lib_nopmod_id;

Modified: development/source/main/cInstSet.h
===================================================================
--- development/source/main/cInstSet.h	2006-11-24 20:50:30 UTC (rev 1099)
+++ development/source/main/cInstSet.h	2006-11-25 21:06:30 UTC (rev 1100)
@@ -51,6 +51,7 @@
     int cost;                 // additional time spent to exectute inst.
     int ft_cost;              // time spent first time exec (in add to cost)
     double prob_fail;         // probability of failing to execute inst
+    int addl_time_cost;       // additional time added to age for executing instruction
   };
   tArray<cInstEntry> m_lib_name_map;
   tArray<int> m_lib_nopmod_map;
@@ -78,6 +79,7 @@
   const cString& GetName(const cInstruction& inst) const { return GetName(inst.GetOp()); }
   int GetCost(const cInstruction& inst) const { return m_lib_name_map[inst.GetOp()].cost; }
   int GetFTCost(const cInstruction& inst) const { return m_lib_name_map[inst.GetOp()].ft_cost; }
+  int GetAddlTimeCost(const cInstruction& inst) const { return m_lib_name_map[inst.GetOp()].addl_time_cost; }
   double GetProbFail(const cInstruction& inst) const { return m_lib_name_map[inst.GetOp()].prob_fail; }
   int GetRedundancy(const cInstruction& inst) const { return m_lib_name_map[inst.GetOp()].redundancy; }
   int GetLibFunctionIndex(const cInstruction& inst) const { return m_lib_name_map[inst.GetOp()].lib_fun_id; }
@@ -98,8 +100,8 @@
   int IsNop(const cInstruction& inst) const { return (inst.GetOp() < m_lib_nopmod_map.GetSize()); }
 
   // Insertion of new instructions...
-  int AddInst(int lib_fun_id, int redundancy = 1, int ft_cost = 0, int cost = 0, double prob_fail = 0.0);
-  int AddNop(int lib_nopmod_id, int redundancy = 1, int ft_cost = 0, int cost = 0, double prob_fail = 0.0);
+  int AddInst(int lib_fun_id, int redundancy = 1, int ft_cost = 0, int cost = 0, double prob_fail = 0.0, int addl_time_cost = 0);
+  int AddNop(int lib_nopmod_id, int redundancy = 1, int ft_cost = 0, int cost = 0, double prob_fail = 0.0, int addl_time_cost = 0);
 
   // accessors for instruction library
   cInstLibBase* GetInstLib() { return m_inst_lib; }

Modified: development/source/main/cPhenotype.h
===================================================================
--- development/source/main/cPhenotype.h	2006-11-24 20:50:30 UTC (rev 1099)
+++ development/source/main/cPhenotype.h	2006-11-25 21:06:30 UTC (rev 1100)
@@ -269,7 +269,7 @@
   void DecCurInstCount(int _inst_num)  { assert(initialized == true); cur_inst_count[_inst_num]--; } 
 
   void IncAge()      { assert(initialized == true); age++; }
-  void IncTimeUsed() { assert(initialized == true); time_used++; }
+  void IncTimeUsed(int i=1) { assert(initialized == true); time_used+=i; }
   void IncErrors()   { assert(initialized == true); cur_num_errors++; }
   void IncDonates()   { assert(initialized == true); cur_num_donates++; }
   void IncSenseCount(const int i) { assert(initialized == true); cur_sense_count[i]++; }  

Modified: development/source/main/cPopulation.cc
===================================================================
--- development/source/main/cPopulation.cc	2006-11-24 20:50:30 UTC (rev 1099)
+++ development/source/main/cPopulation.cc	2006-11-25 21:06:30 UTC (rev 1100)
@@ -44,6 +44,7 @@
 
 #include <float.h>
 #include <math.h>
+#include <limits.h>
 
 using namespace std;
 
@@ -1285,6 +1286,27 @@
     if (out_cell_id == cell_array.GetSize()) out_cell_id = 0;
     return GetCell(out_cell_id);
   }
+    else if (birth_method == POSITION_CHILD_FULL_SOUP_TIME_USED) {
+    tList<cPopulationCell> found_list;
+    int max_time_used = 0;
+    for  (int i=0; i < cell_array.GetSize(); i++)
+    {
+      int time_used = cell_array[i].IsOccupied() ? cell_array[i].GetOrganism()->GetPhenotype().GetTimeUsed() : INT_MAX;
+      if (time_used == max_time_used)
+      {
+        found_list.Push(&cell_array[i]);
+      }
+      else if (time_used > max_time_used)
+      {
+        max_time_used = time_used;
+        found_list.Clear();
+        found_list.Push(&cell_array[i]);
+      }
+    }
+    int choice = m_world->GetRandom().GetUInt(found_list.GetSize());
+    return *( found_list.GetPos(choice) );
+  }
+  
 
   // All remaining methods require us to choose among mulitple local positions.
 




More information about the Avida-cvs mailing list