[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