[Avida-SVN] r3447 - development/source/main
dk at myxo.css.msu.edu
dk at myxo.css.msu.edu
Mon Oct 5 12:54:41 PDT 2009
Author: dk
Date: 2009-10-05 15:54:41 -0400 (Mon, 05 Oct 2009)
New Revision: 3447
Modified:
development/source/main/cEventList.cc
development/source/main/cEventList.h
development/source/main/cPopulation.cc
development/source/main/cPopulation.h
development/source/main/cStats.cc
Log:
Added sanity checking to flash instruction to prevent memory explosion, fixed DEMES_PREVENT_STERILE for tournament selection.
Modified: development/source/main/cEventList.cc
===================================================================
--- development/source/main/cEventList.cc 2009-10-05 19:49:27 UTC (rev 3446)
+++ development/source/main/cEventList.cc 2009-10-05 19:54:41 UTC (rev 3447)
@@ -471,3 +471,17 @@
return AddEvent(trigger, start, interval, stop, name, arg_list);
}
+
+
+/*! Check to see if an event with the given name is upcoming at some point in the future.
+ */
+bool cEventList::IsEventUpcoming(const cString& event_name) {
+ cEventListEntry* entry = m_head;
+ while(entry != 0) {
+ if(entry->GetName() == event_name) {
+ return true;
+ }
+ entry = entry->GetNext();
+ }
+ return false;
+}
Modified: development/source/main/cEventList.h
===================================================================
--- development/source/main/cEventList.h 2009-10-05 19:49:27 UTC (rev 3446)
+++ development/source/main/cEventList.h 2009-10-05 19:54:41 UTC (rev 3447)
@@ -213,6 +213,9 @@
* @param ctx Avida context
**/
void ProcessInterrupt(cAvidaContext& ctx);
+
+ //! Check to see if an event with the given name is upcoming at some point in the future.
+ bool IsEventUpcoming(const cString& event_name);
};
Modified: development/source/main/cPopulation.cc
===================================================================
--- development/source/main/cPopulation.cc 2009-10-05 19:49:27 UTC (rev 3446)
+++ development/source/main/cPopulation.cc 2009-10-05 19:54:41 UTC (rev 3447)
@@ -1255,12 +1255,16 @@
for backwards compatibility), change the config option DEMES_REPLICATE_SIZE to be the size of
each deme.
*/
-void cPopulation::CompeteDemes(std::vector<double>& fitness) {
+void cPopulation::CompeteDemes(const std::vector<double>& calculated_fitness) {
+ // it's possible that we'll be changing the fitness values of some demes, so make a copy:
+ std::vector<double> fitness(calculated_fitness);
+
// Each deme must have a fitness:
assert((int)fitness.size() == deme_array.GetSize());
// To prevent sterile demes from replicating, we're going to replace the fitness
- // of all sterile demes with 0.
+ // of all sterile demes with 0; this effectively makes it impossible for a sterile
+ // deme to be selected via fitness proportional selection.
if(m_world->GetConfig().DEMES_PREVENT_STERILE.Get()) {
for(int i=0; i<deme_array.GetSize(); ++i) {
if(deme_array[i].GetBirthCount() == 0) {
@@ -1313,10 +1317,20 @@
// We run NUM_DEMES tournaments of size DEME_TOURNAMENT_SIZE, and select the
// **single** winner of the tournament to proceed to the next generation.
- // We need a list of all possible deme_ids so that we can pull samples from it.
- std::vector<int> deme_ids(deme_array.GetSize());
- for(int i=0; i<(int)deme_ids.size(); ++i) { deme_ids[i] = i; }
+ // construct a list of all possible deme ids that could participate in a tournament,
+ // pruning out sterile demes:
+ std::vector<int> deme_ids;
+ for(int i=0; i<deme_array.GetSize(); ++i) {
+ if(!m_world->GetConfig().DEMES_PREVENT_STERILE.Get() || (deme_array[i].GetBirthCount() > 0)) {
+ deme_ids.push_back(i);
+ }
+ }
+ // better have more than deme tournament size, otherwise something is *really* screwed up:
+ if(m_world->GetConfig().DEMES_TOURNAMENT_SIZE.Get() > static_cast<int>(deme_ids.size())) {
+ m_world->GetDriver().RaiseFatalException(-1, "The number of demes that can participate in a tournament is less than the deme tournament size.");
+ }
+
// Run the tournaments.
for(int i=0; i<m_world->GetConfig().NUM_DEMES.Get(); ++i) {
// Which demes are in this tournament?
Modified: development/source/main/cPopulation.h
===================================================================
--- development/source/main/cPopulation.h 2009-10-05 19:49:27 UTC (rev 3446)
+++ development/source/main/cPopulation.h 2009-10-05 19:54:41 UTC (rev 3447)
@@ -197,7 +197,7 @@
void CompeteDemes(int competition_type);
//! Compete all demes with each other based on the given vector of fitness values.
- void CompeteDemes(std::vector<double>& fitness);
+ void CompeteDemes(const std::vector<double>& calculated_fitness);
//! Replicate all demes based on the given replication trigger.
void ReplicateDemes(int rep_trigger);
Modified: development/source/main/cStats.cc
===================================================================
--- development/source/main/cStats.cc 2009-10-05 19:49:27 UTC (rev 3446)
+++ development/source/main/cStats.cc 2009-10-05 19:54:41 UTC (rev 3447)
@@ -2365,9 +2365,24 @@
We do some pretty detailed tracking here in order to support the use of flash
messages in deme competition. All flashes are tracked per deme.
+
+ Because we're tracking highly detailed information about flashes, if
+ someone forgets to include the print event for synchronization, it's highly
+ likely that Avida will run out of memory (not that this has happened *ahem*).
+ So, the first time this method is called, we check to make sure that at least one
+ of the print events is also called, otherwise we throw an error.
*/
void cStats::SentFlash(cOrganism& organism) {
- ++m_flash_count;
+ static bool event_checked=false;
+ if(!event_checked && (m_world->GetEventsList() != 0)) {
+ if(!m_world->GetEventsList()->IsEventUpcoming("PrintSynchronizationData")
+ && !m_world->GetEventsList()->IsEventUpcoming("PrintDetailedSynchronizationData")) {
+ m_world->GetDriver().RaiseFatalException(-1, "When using the flash instruction, either the PrintSynchronizationData or PrintDetailedSynchronizationData events must also be used.");
+ }
+ event_checked = true;
+ }
+
+ ++m_flash_count;
if(organism.GetOrgInterface().GetDeme() != 0) {
const cDeme* deme = organism.GetOrgInterface().GetDeme();
m_flash_times[GetUpdate()][deme->GetID()].push_back(deme->GetRelativeCellID(organism.GetCellID()));
More information about the Avida-cvs
mailing list