[Avida-SVN] r2784 - branches/movement/source/main
welsberr at myxo.css.msu.edu
welsberr at myxo.css.msu.edu
Sun Sep 14 16:26:47 PDT 2008
Author: welsberr
Date: 2008-09-14 19:26:47 -0400 (Sun, 14 Sep 2008)
New Revision: 2784
Modified:
branches/movement/source/main/cPopulation.cc
branches/movement/source/main/cPopulation.h
Log:
Add tumble method for changing facing; revised carrying capacity strategy
Modified: branches/movement/source/main/cPopulation.cc
===================================================================
--- branches/movement/source/main/cPopulation.cc 2008-09-14 22:08:37 UTC (rev 2783)
+++ branches/movement/source/main/cPopulation.cc 2008-09-14 23:26:47 UTC (rev 2784)
@@ -419,7 +419,57 @@
child_genotype->DecDeferAdjust();
m_world->GetClassificationManager().AdjustGenotype(*child_genotype);
}
-
+
+ // @WRE carrying capacity handling
+ /* Randomly pick and kill an organism here if needed */
+ /* @WRE: Notes on carrying capacity, 13-Sep-2008
+ Previous placement of similar code within "PositionChild" could cause
+ runtime failure, apparently due to killing off parent organisms
+ prematurely.
+ This code is aimed at providing an interim carrying capacity capability.
+ A final version will need to take into account carrying capacity for
+ demes. This code has not been tested in a deme context.
+ */
+ if ((0 < m_world->GetConfig().BIOMIMETIC_K.Get()) &&
+ (num_organisms > m_world->GetConfig().BIOMIMETIC_K.Get())) {
+ int max_msrndx = 0;
+
+ // Handle small population limit with SerialTransfer
+ if (3 >= m_world->GetConfig().BIOMIMETIC_K.Get()) {
+ // Call SerialTransfer
+ SerialTransfer(m_world->GetConfig().BIOMIMETIC_K.Get(),1);
+ // @WRE: Note: There is no check here for the parent having been killed by
+ // SerialTransfer, so the "parent_alive" flag should not be relied upon
+ // when small population sizes are chosen.
+ } else {
+ // Alternate pick method; essentially a lottery
+ // Measure temporary variables
+ double max_msr = 0.0;
+ double msr = 0.0;
+ for (int i=0; i < cell_array.GetSize(); i++) {
+ if (cell_array[i].IsOccupied()) {
+ if (cell_array[i].GetOrganism()->GetPhenotype().OK()) {
+ // The call to GetRandom() will make carrying capacity runs differ from scenarios in
+ // the consistency tests.
+ msr = m_world->GetRandom().GetDouble();
+ } else {
+ // Can't validate an organism, so rank the cell at the bottom of the lottery
+ msr = 0.0;
+ }
+ // Update the current lottery pick
+ if (max_msr < msr) {
+ max_msr = msr;
+ max_msrndx = i;
+ }
+ }
+ }
+ // Check for killing off the parent
+ if (cell_array[max_msrndx].GetID() == parent_cell.GetID()) parent_alive = false;
+ // Actually perform the kill.
+ KillOrganism(cell_array[max_msrndx]);
+ } // end alternate pick method
+ } // end carrying capacity implementation
+
return parent_alive;
}
@@ -473,6 +523,13 @@
in_organism->SetOrgInterface(new cPopulationInterface(m_world));
+ // @WRE: Hard limit to keep the total number of organisms ever in a run to a specific number. 13-Sep-2008
+ if ((0 < m_world->GetConfig().BIOMIMETIC_HARD_LIMIT.Get()) &&
+ (m_world->GetConfig().BIOMIMETIC_HARD_LIMIT.Get() <= m_world->GetStats().GetTotCreatures())) {
+ // Once the limit is reached, we simply never activate another organism.
+ return;
+ }
+
// If the organism does not have a genotype, give it one! No parent
// information is provided so we must set parents to NULL.
if (in_organism->GetGenotype() == NULL) {
@@ -570,6 +627,13 @@
if ( m_world->GetConfig().IDEAL_GRAD_ON.Get() ) {
in_organism->SetTargetCell();
}
+
+ // @WRE: Tumble the new organism if movement is turned on. 08-Aug-2008
+ if (0 != m_world->GetConfig().BIOMIMETIC_MOVEMENT_STEP.Get()) {
+ // This randomizes the initial facing.
+ Tumble(in_organism);
+ }
+
}
// @WRE 2007/07/05 Helper function to take care of side effects of Avidian
@@ -578,9 +642,6 @@
{
// Declarations
int actualNeighborhoodSize, fromFacing, destFacing, newFacing, success;
-#ifdef DEBBUG
- int sID, dID, xx1, yy1, xx2, yy2;
-#endif
// Swap inputs between cells to fix bus error when Avidian moves into an unoccupied cell
environment.SwapInputs(ctx, src_cell.m_inputs, dest_cell.m_inputs);
@@ -609,60 +670,39 @@
for(int i = 0; i < actualNeighborhoodSize; i++) {
if (src_cell.GetFacing() != newFacing) {
src_cell.ConnectionList().CircNext();
- //cout << "MO: src_cell facing not yet at " << newFacing << endl;
} else {
- //cout << "MO: src_cell facing successfully set to " << newFacing << endl;
success = 1;
break;
}
}
- // @DMB this doesn't compile properly -- #ifdef DEBUG
-#if 0
- if (!success) {
- sID = src_cell.GetID();
- dID = dest_cell.GetID();
- src_cell.GetPosition(xx1,yy1);
- dest_cell.GetPosition(xx2,yy2);
- //Conditional for examining only neighbor move without swap in facing
- //if (1 == abs(xx2-xx1)+abs(yy2-yy1)) {
- cout << "MO: src: " << sID << "@ (" << xx1 << "," << yy1 << ") dest: " << dID << "@ (" << xx2 << "," << yy2 << "), FAILED to set src_cell facing to " << newFacing << endl;
- for (int j=0; j < actualNeighborhoodSize; j++) {
- src_cell.ConnectionList().CircNext();
- src_cell.GetCellFaced().GetPosition(xx2,yy2);
- cout << "connlist for " << sID << ": facing " << src_cell.GetFacing() << " -> (" << xx2 << "," << yy2 << ")" << endl;
+
+ // @WRE: Randomize facing if it isn't exactly the same as before. 08-Aug-2008
+ if ((!success) && src_cell.IsOccupied()) {
+ if (0 != m_world->GetConfig().BIOMIMETIC_MOVEMENT_STEP.Get()) {
+ Tumble(src_cell.GetOrganism());
+ }
+ }
+
+ // Set facing in destination cell
+ success = 0;
+ newFacing = fromFacing;
+ for(int i = 0; i < actualNeighborhoodSize; i++) {
+ if (dest_cell.GetFacing() != newFacing) {
+ dest_cell.ConnectionList().CircNext();
+ } else {
+ success = 1;
+ break;
}
- //}
}
-#endif
-// Set facing in destinatiion cell
-success = 0;
-newFacing = fromFacing;
-for(int i = 0; i < actualNeighborhoodSize; i++) {
- if (dest_cell.GetFacing() != newFacing) {
- dest_cell.ConnectionList().CircNext();
- // cout << "MO: dest_cell facing not yet at " << newFacing << endl;
- } else {
- // cout << "MO: dest_cell facing successfully set to " << newFacing << endl;
- success = 1;
- break;
+ // @WRE: Randomize facing if it isn't exactly the same as before
+ if ((!success) && dest_cell.IsOccupied()) {
+ if (0 != m_world->GetConfig().BIOMIMETIC_MOVEMENT_STEP.Get()) {
+ Tumble(src_cell.GetOrganism());
+ }
}
}
-// @DMB this doesn't compile properly -- #ifdef DEBUG
-#if 0
-if (!success) {
- sID = src_cell.GetID();
- dID = dest_cell.GetID();
- src_cell.GetPosition(xx1,yy1);
- dest_cell.GetPosition(xx2,yy2);
- if (1 == abs(xx2-xx1)+abs(yy2-yy1)) {
- cout << "MO: src: " << sID << "@ (" << xx1 << "," << yy1 << ") dest: " << dID << "@ (" << xx2 << "," << yy2 << "), FAILED to set dest_cell facing to " << newFacing << endl;
- }
-}
-#endif
-}
-
void cPopulation::KillOrganism(cPopulationCell& in_cell)
{
// do we actually have something to kill?
@@ -3003,41 +3043,11 @@
assert(parent_cell.IsOccupied());
const int birth_method = m_world->GetConfig().BIRTH_METHOD.Get();
-
- // @WRE carrying capacity handling
- /* Randomly pick and kill an organism here if needed
- * and then enter choices for birth method handling.
- */
- if ((0 < m_world->GetConfig().BIOMIMETIC_K.Get()) &&
- (num_organisms >= m_world->GetConfig().BIOMIMETIC_K.Get())) {
- // Measure temporary variables
- double max_msr = 0.0;
- double msr = 0.0;
- int max_msrndx = 0;
- for (int i=0; i < cell_array.GetSize(); i++) {
- if (cell_array[i].IsOccupied()) {
- if (cell_array[i].GetOrganism()->GetPhenotype().OK()) {
- // Get measurement, exclude parent
- if ((parent_cell.GetID() != cell_array[i].GetID()) ||
- (3 > num_organisms)) { // Make an exception for tiny populations. @WRE 04-Sep-08
- msr = m_world->GetRandom().GetDouble();
- } else {
- msr = 0.0;
- }
- if (max_msr < msr) {
- max_msr = msr;
- max_msrndx = i;
- }
- }
- }
- }
- KillOrganism(cell_array[max_msrndx]);
- }
-
+
//@AWC -- decide whether the child will migrate to another deme -- if migrating we ignore the birth method.
if ((m_world->GetConfig().MIGRATION_RATE.Get() > 0.0) //@AWC -- Pedantic test to maintain consistency.
&& m_world->GetRandom().P(m_world->GetConfig().MIGRATION_RATE.Get())) {
-
+
//cerr << "Attempting to migrate with rate " << m_world->GetConfig().MIGRATION_RATE.Get() << "!" << endl;
int deme_id = parent_cell.GetDemeID();
@@ -5133,3 +5143,27 @@
}
}
+
+// @WRE: Adding method to allow "tumble" for organisms. 09-Aug-2008
+// Rationale for this method: Movement studies make use of facing as an
+// element. Standard Avida treatment of facing can result in regularities
+// in absolute initial facing and in turns made in bounded grids when a
+// facing becomes invalid. This method is used to randomize facings in
+// such circumstances.
+void cPopulation::Tumble(cOrganism* organism)
+{
+ // Get the context
+ cAvidaContext& ctx = m_world->GetDefaultContext();
+ // Get number of neighbor cells that the organism can move to.
+ const int num_neighbors = organism->GetNeighborhoodSize();
+ // Exclude extreme case of the completely disconnected cell
+ if (0 < num_neighbors) {
+ // Choose a base 0 random number of turns to make in facing.
+ int irot = ctx.GetRandom().GetUInt(num_neighbors-1);
+ // Treat as base 0 number of turns to make.
+ for (int i = 0; i <= irot; i++) {
+ organism->Rotate(1);
+ }
+ }
+}
+
Modified: branches/movement/source/main/cPopulation.h
===================================================================
--- branches/movement/source/main/cPopulation.h 2008-09-14 22:08:37 UTC (rev 2783)
+++ branches/movement/source/main/cPopulation.h 2008-09-14 23:26:47 UTC (rev 2784)
@@ -317,6 +317,9 @@
// Let users change environmental variables durning the run @BDB 22-Feb-2008
void UpdateResourceCount(const int Verbosity);
+
+ // @WRE: Make a method to provide "tumble" capability 08-Aug-2008
+ void cPopulation::Tumble(cOrganism* organism);
};
More information about the Avida-cvs
mailing list