[Avida-SVN] r2915 - in development: source/analyze source/cpu source/drivers source/main tests/fitvalley_dynamic_mutrate

jbarrick at myxo.css.msu.edu jbarrick at myxo.css.msu.edu
Sat Nov 1 19:21:30 PDT 2008


Author: jbarrick
Date: 2008-11-01 22:21:30 -0400 (Sat, 01 Nov 2008)
New Revision: 2915

Modified:
   development/source/analyze/cAnalyze.cc
   development/source/cpu/cHardwareBase.cc
   development/source/cpu/cHardwareBase.h
   development/source/cpu/cHardwareCPU.cc
   development/source/drivers/cDefaultRunDriver.cc
   development/source/main/cAvidaConfig.h
   development/tests/fitvalley_dynamic_mutrate/test_list
Log:
cHardwareCPU::Inst_Repro now does Divide_CheckViable tests. Analyze command FindLastCommonAncestor now works, if slowly. 



Modified: development/source/analyze/cAnalyze.cc
===================================================================
--- development/source/analyze/cAnalyze.cc	2008-11-02 01:35:35 UTC (rev 2914)
+++ development/source/analyze/cAnalyze.cc	2008-11-02 02:21:30 UTC (rev 2915)
@@ -1442,139 +1442,73 @@
 void cAnalyze::FindLastCommonAncestor(cString cur_string)
 {  
 
-/*
   // Assumes that the current batch contains a population and all of its common ancestors
   // Finds the last common ancestor among all current organisms that are still alive,
   // i.e. have an update_died of -1.
 
   cout << "Finding last common ancestor of batch " << cur_batch << endl;
   
-  // Make a list of alive organisms
-  tListPlus<cAnalyzeGenotype> alive_list;
-  {
-    tListIterator<cAnalyzeGenotype> batch_it(batch[cur_batch].List());
-    cAnalyzeGenotype * test_genotype = NULL;
-    while ((test_genotype = batch_it.Next()) != NULL) {
-      if (test_genotype->GetUpdateDead() == -1) {
-        alive_list.Push(test_genotype);
-      }
-    }
-  }
-  
   if (m_world->GetVerbosity() >= VERBOSE_ON) {
-    cout << "  Number of genotypes that are alive: " << alive_list.GetSize() << endl;
-    cout << "  Number of ancestor genotypes: " << batch[cur_batch].List().GetSize() << endl;
+    cout << "  Connecting genotypes to parents. " << endl;
   }
-    
-  // Extract the lineage of the first alive organism.
-  // The LCA must be among these genotypes. The approach is to step back one ancestor
-  // at a time, collect all of its descendants, and then check to see if there are
-  // andy alive organisms that have not been collected yet.
   
-  // find the lineage of the first genotype...
-  cAnalyzeGenotype * first_alive_genotype = alive_list.Pop();
-  tListPlus<cAnalyzeGenotype> master_lineage;
-  {
-    master_lineage.Push(first_alive_genotype);
-    int next_id = first_alive_genotype->GetParentID();
-    bool found = true;
-    while (found == true) {
-      found = false;
-      
-      tListIterator<cAnalyzeGenotype> batch_it(batch[cur_batch].List());
-      cAnalyzeGenotype * found_gen = NULL;
-      while ((found_gen = batch_it.Next()) != NULL) {
-        if (found_gen->GetID() == next_id) {
-          master_lineage.Push(found_gen);
-          next_id = found_gen->GetParentID();
-          found = true;
-          break;
-        }
+  // Connect each genotype to its parent.
+  tListIterator<cAnalyzeGenotype> child_it(batch[cur_batch].List());
+  cAnalyzeGenotype * on_child = NULL;
+  while ((on_child = child_it.Next()) != NULL) {
+    tListIterator<cAnalyzeGenotype> parent_it(batch[cur_batch].List());
+    cAnalyzeGenotype * on_parent = NULL;
+    while ((on_parent = parent_it.Next()) != NULL) {
+      if (on_child->GetParentID() == on_parent->GetID()) {
+        on_child->LinkParent(on_parent);
+        break;
       }
     }
   }
- 
+
   if (m_world->GetVerbosity() >= VERBOSE_ON) {
-    cout << "  Size of master lineage: " << master_lineage.GetSize() << endl;
+    cout << "  Finding earliest genotype. " << endl;
   }
-    
-  tListIterator<cAnalyzeGenotype> master_lineage_batch_it(master_lineage);
   
-  while ((collect_genotype = master_lineage_batch_it.Next()) != NULL) {
-    
-    // collect all children of the current lineage genotype
-    tListPlus<cAnalyzeGenotype> collect_genotype_list;
-    collect_genotype_list.PushRear(collect_genotype);
-    tListIterator<cAnalyzeGenotype> collect_batch_it(collect_genotype_list);
-    
-    next_collect_genotype_list;
-    
-    int current_id = alive_genotype->GetID();
-    int parent_id = alive_genotype->GetParentID();
-    bool found_parent = true;
-    bool found_in_master_lineage = false;
-    while (found_parent == true) {
-        
-      // Check to see if this id is among those in the first lineage.       
-      tListIterator<cAnalyzeGenotype> master_lineage_batch_it(master_lineage);
-      cAnalyzeGenotype * master_lineage_genotype;
-      while ((master_lineage_genotype = master_lineage_batch_it.Next()) != NULL) {
-        if (master_lineage_genotype->GetID() == current_id) break;
+  // Find the genotype without a parent (there should only be one)
+  tListIterator<cAnalyzeGenotype> first_lca_it(batch[cur_batch].List());
+  cAnalyzeGenotype * lca = NULL;
+  cAnalyzeGenotype * test_lca = NULL;
+  while ((test_lca = first_lca_it.Next()) != NULL) {
+    if (!test_lca->GetParent()) {
+      // It is an error to get two genotypes without a parent
+      if (lca != NULL) {
+        cout << "Error: More than one genotype does not have a parent. " << endl;
+        cout << "Genotype 1: " << test_lca->GetID() << endl;
+        cout << "Genotype 2: " << lca->GetID() << endl;
+        return;
       }
-
-      found_in_master_lineage = master_lineage_genotype != NULL;
-      if (found_in_master_lineage) {
-        
-        // Remove anything in the master lineage that is past this point.
-        // as it is younger than the new most recent common ancestor
-        while ((master_lineage_genotype = master_lineage_batch_it.Next()) != NULL) {
-          master_lineage_batch_it.Remove();
-        }
-        
-        // We can also stop looking at ancestors of the current alive_genotype
-        if (found_in_master_lineage) break;
-      }
-      
-      // Find the ancestor of the current organism in the alive_genotype lineage
-      found_parent = false;      
-      tListIterator<cAnalyzeGenotype> batch_it(batch[cur_batch].List());
-      cAnalyzeGenotype * test_genotype = NULL;
-      while ((test_genotype = batch_it.Next()) != NULL) {
-        if (test_genotype->GetID() == parent_id) {
-          parent_id = test_genotype->GetParentID();
-          current_id = test_genotype->GetID();
-          found_parent = true;
-          break;
-        }
-      }
+      lca = test_lca;
     }
-    
-    // Warn if we did not find a common ancestor at all.
-    if (!found_in_master_lineage) { 
-      cout << "  Warning! Did not find common ancestor between two organisms. " << endl;
-    }
-    
-    if (m_world->GetVerbosity() >= VERBOSE_ON) {
-      cout << "  Size of master lineage: " << master_lineage.GetSize() << endl;
-    }
   }
   
-  // The first one left in this lineage is the one we want to save.
-  cAnalyzeGenotype * last_common_ancestor = master_lineage.Pop();
+  if (m_world->GetVerbosity() >= VERBOSE_ON) {
+    cout << "  Following children to last common ancestor. " << endl;
+  }
   
+  // Follow the children from this parent until we find a genotype with 
+  // more than one child. This is the last common ancestor.
+  while (lca->GetChildList().GetSize() == 1) {
+    lca = lca->GetChildList().Pop();
+  }
+  
   // Delete everything else.
   tListIterator<cAnalyzeGenotype> delete_batch_it(batch[cur_batch].List());
   cAnalyzeGenotype * delete_genotype = NULL;
   while ((delete_genotype = delete_batch_it.Next()) != NULL) {
-    if (delete_genotype->GetID() != last_common_ancestor->GetID()) {
-      delete batch[cur_batch].List().Pop();
+    if (delete_genotype->GetID() != lca->GetID()) {
+      delete delete_genotype;
     }
   }
   
   // And fill it back in with the good stuff.
-  batch[cur_batch].List().PushRear(last_common_ancestor);
-
-  */
+  batch[cur_batch].List().Clear();
+  batch[cur_batch].List().PushRear(lca);
 }
 
 

Modified: development/source/cpu/cHardwareBase.cc
===================================================================
--- development/source/cpu/cHardwareBase.cc	2008-11-02 01:35:35 UTC (rev 2914)
+++ development/source/cpu/cHardwareBase.cc	2008-11-02 02:21:30 UTC (rev 2915)
@@ -58,7 +58,7 @@
   return executed_size;
 }
 
-bool cHardwareBase::Divide_CheckViable(cAvidaContext& ctx, const int parent_size, const int child_size)
+bool cHardwareBase::Divide_CheckViable(cAvidaContext& ctx, const int parent_size, const int child_size, bool using_repro)
 {
   // Make sure the organism is okay with dividing now...
   if (organism->Divide_CheckViable() == false) return false; // (divide fails)
@@ -80,6 +80,21 @@
     return false; // (divide fails)
   }
   
+  // Absolute minimum and maximum child/parent size limits -- @JEB
+  const int max_genome_size = m_world->GetConfig().MAX_GENOME_SIZE.Get();
+  const int min_genome_size = m_world->GetConfig().MIN_GENOME_SIZE.Get();
+  if ( (min_genome_size && (child_size < min_genome_size)) || (max_genome_size && (child_size > max_genome_size)) ) {
+    organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+                    cStringUtil::Stringf("Invalid absolute offspring length (%d)",child_size));
+    return false; // (divide fails)
+  }
+  
+  if ( (min_genome_size && (parent_size < min_genome_size)) || (max_genome_size && (parent_size > max_genome_size)) ) {
+    organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+                    cStringUtil::Stringf("Invalid absolute post-divide length (%d)",parent_size));
+    return false; // (divide fails)
+  }
+  
   // Count the number of lines executed in the parent, and make sure the
   // specified fraction has been reached.
   
@@ -90,15 +105,22 @@
                     cStringUtil::Stringf("Too few executed lines (%d < %d)", executed_size, min_exe_lines));
     return false; // (divide fails)
   }
-	
-  const int copied_size = GetCopiedSize(parent_size, child_size);
-  const int min_copied = static_cast<int>(child_size * m_world->GetConfig().MIN_COPIED_LINES.Get());
-  if (copied_size < min_copied) {
-    organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-                    cStringUtil::Stringf("Too few copied commands (%d < %d)", copied_size, min_copied));
-    return false; // (divide fails)
+  
+  // Repro organisms mark their entire genomes as copied
+  int copied_size = parent_size;
+  if (!using_repro) {
+    // Normal organisms check to see how much was copied
+    copied_size = GetCopiedSize(parent_size, child_size); // Fails for REPRO organisms
+    const int min_copied = static_cast<int>(child_size * m_world->GetConfig().MIN_COPIED_LINES.Get());
+  
+    if (copied_size < min_copied) {
+
+      organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+                      cStringUtil::Stringf("Too few copied commands (%d < %d)", copied_size, min_copied));
+      return false; // (divide fails)
+    }
   }
-  
+   
   // Save the information we collected here...
   cPhenotype& phenotype = organism->GetPhenotype();
   phenotype.SetLinesExecuted(executed_size);

Modified: development/source/cpu/cHardwareBase.h
===================================================================
--- development/source/cpu/cHardwareBase.h	2008-11-02 01:35:35 UTC (rev 2914)
+++ development/source/cpu/cHardwareBase.h	2008-11-02 02:21:30 UTC (rev 2915)
@@ -72,7 +72,7 @@
   virtual int GetExecutedSize(const int parent_size);
   virtual int GetCopiedSize(const int parent_size, const int child_size) = 0;  
   
-  bool Divide_CheckViable(cAvidaContext& ctx, const int parent_size, const int child_size);
+  bool Divide_CheckViable(cAvidaContext& ctx, const int parent_size, const int child_size, bool using_repro = false);
 
 protected:
   unsigned Divide_DoExactMutations(cAvidaContext& ctx, double mut_multiplier = 1.0, const int pointmut = INT_MAX);

Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc	2008-11-02 01:35:35 UTC (rev 2914)
+++ development/source/cpu/cHardwareCPU.cc	2008-11-02 02:21:30 UTC (rev 2915)
@@ -2692,11 +2692,7 @@
 }
 
 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
-  
+{ 
   // check if repro can replace an existing organism
   if(m_world->GetConfig().REPRO_METHOD.Get() == 0 && organism->IsNeighborCellOccupied())
     return false;
@@ -2705,15 +2701,8 @@
   
   // Setup child
   cCPUMemory& child_genome = organism->ChildGenome();
-  child_genome = m_memory;
-  organism->GetPhenotype().SetLinesCopied(m_memory.GetSize());
+  child_genome = organism->GetGenome();
 
-  int lines_executed = 0;
-  for ( int i = 0; i < m_memory.GetSize(); i++ ) {
-    if ( m_memory.FlagExecuted(i)) lines_executed++;
-  }
-  organism->GetPhenotype().SetLinesExecuted(lines_executed);
-  
   // Do transposon movement and copying before other mutations
   Divide_DoTransposons(ctx);
   
@@ -2729,6 +2718,10 @@
   
   Divide_DoMutations(ctx);
   
+  // Check viability
+  bool viable = Divide_CheckViable(ctx, organism->GetGenome().GetSize(), organism->ChildGenome().GetSize(), 1);
+  if (!viable) { return false; }
+  
   // Many tests will require us to run the offspring through a test CPU;
   // this is, for example, to see if mutations need to be reverted or if
   // lineages need to be updated.

Modified: development/source/drivers/cDefaultRunDriver.cc
===================================================================
--- development/source/drivers/cDefaultRunDriver.cc	2008-11-02 01:35:35 UTC (rev 2914)
+++ development/source/drivers/cDefaultRunDriver.cc	2008-11-02 02:21:30 UTC (rev 2915)
@@ -74,7 +74,7 @@
   
   void (cPopulation::*ActiveProcessStep)(cAvidaContext& ctx, double step_size, int cell_id) = &cPopulation::ProcessStep;
   if (m_world->GetHardwareManager().SupportsSpeculative() && m_world->GetConfig().SPECULATIVE.Get() &&
-      m_world->GetConfig().THREAD_SLICING_METHOD.Get() != 1) {
+      m_world->GetConfig().THREAD_SLICING_METHOD.Get() != 1 && !m_world->GetConfig().IMPLICIT_REPRO_END.Get()) {
     ActiveProcessStep = &cPopulation::ProcessStepSpeculative;
   }
   

Modified: development/source/main/cAvidaConfig.h
===================================================================
--- development/source/main/cAvidaConfig.h	2008-11-02 01:35:35 UTC (rev 2914)
+++ development/source/main/cAvidaConfig.h	2008-11-02 02:21:30 UTC (rev 2915)
@@ -359,6 +359,8 @@
   CONFIG_ADD_VAR(CHILD_SIZE_RANGE, double, 2.0, "Maximal differential between child and parent sizes.");
   CONFIG_ADD_VAR(MIN_COPIED_LINES, double, 0.5, "Code fraction which must be copied before divide.");
   CONFIG_ADD_VAR(MIN_EXE_LINES, double, 0.5, "Code fraction which must be executed before divide.");
+  CONFIG_ADD_VAR(MIN_GENOME_SIZE, int, 0, "Minimum number of instructions allowed in a genome. 0 = OFF");
+  CONFIG_ADD_VAR(MAX_GENOME_SIZE, int, 0, "Maximum number of instructions allowed in a genome. 0 = OFF");
   CONFIG_ADD_VAR(REQUIRE_ALLOCATE, int, 1, "(Original CPU Only) Require allocate before divide?");
   CONFIG_ADD_VAR(REQUIRED_TASK, int, -1, "Task ID required for successful divide.");
   CONFIG_ADD_VAR(IMMUNITY_TASK, int, -1, "Task providing immunity from the required task.");

Modified: development/tests/fitvalley_dynamic_mutrate/test_list
===================================================================
--- development/tests/fitvalley_dynamic_mutrate/test_list	2008-11-02 01:35:35 UTC (rev 2914)
+++ development/tests/fitvalley_dynamic_mutrate/test_list	2008-11-02 02:21:30 UTC (rev 2915)
@@ -1,7 +1,7 @@
 ;--- Begin Test Configuration File (test_list) ---
 [main]
 ; Command line arguments to pass to the application
-args = -s 1 -set CHILD_SIZE_RANGE 1 -set DIVIDE_INS_PROB 0 -set DIVIDE_DEL_PROB 0 -set INST_SET instset-reprosA-B.cfg -set START_CREATURE 10reproAs.org -set BASE_MERIT_METHOD 6 -set WORLD_X 10 -set WORLD_Y 10 -set MERIT_BONUS_INST 2 -set COPY_MUT_PROB .1 -set MERIT_BONUS_EFFECT 1 -set EVENT_FILE events-toggleEvery10.cfg -v2 -set META_COPY_MUT .5 -set META_STD_DEV  .1 -set MUT_RATE_SOURCE 2 -set NUM_DEMES 1 -set FITNESS_VALLEY 1 -set FITNESS_VALLEY_START 5 -set FITNESS_VALLEY_STOP 6 
+args = -s 1 -set CHILD_SIZE_RANGE 1 -set DIVIDE_INS_PROB 0  -set MIN_EXE_LINES 0 -set DIVIDE_DEL_PROB 0 -set INST_SET instset-reprosA-B.cfg -set START_CREATURE 10reproAs.org -set BASE_MERIT_METHOD 6 -set WORLD_X 10 -set WORLD_Y 10 -set MERIT_BONUS_INST 2 -set COPY_MUT_PROB .1 -set MERIT_BONUS_EFFECT 1 -set EVENT_FILE events-toggleEvery10.cfg -v2 -set META_COPY_MUT .5 -set META_STD_DEV  .1 -set MUT_RATE_SOURCE 2 -set NUM_DEMES 1 -set FITNESS_VALLEY 1 -set FITNESS_VALLEY_START 5 -set FITNESS_VALLEY_STOP 6 
 
 app = %(default_app)s
 nonzeroexit = disallow   ; Exit code handling (disallow, allow, or require)




More information about the Avida-cvs mailing list