[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