[Avida-SVN] r1370 - in branches/dkdev: Avida.xcodeproj source/actions source/cpu source/main

dknoester at myxo.css.msu.edu dknoester at myxo.css.msu.edu
Sun Feb 25 17:09:53 PST 2007


Author: dknoester
Date: 2007-02-25 20:09:53 -0500 (Sun, 25 Feb 2007)
New Revision: 1370

Modified:
   branches/dkdev/Avida.xcodeproj/project.pbxproj
   branches/dkdev/source/actions/PopulationActions.cc
   branches/dkdev/source/actions/PrintActions.cc
   branches/dkdev/source/cpu/cHardwareCPU.cc
   branches/dkdev/source/cpu/cHardwareCPU.h
   branches/dkdev/source/main/cDeme.cc
   branches/dkdev/source/main/cDeme.h
   branches/dkdev/source/main/cPopulation.cc
   branches/dkdev/source/main/cStats.cc
   branches/dkdev/source/main/cStats.h
Log:
Checkpoint commit for topology work.  Using ReplicateDemes and checking for completely connected topologies.

Modified: branches/dkdev/Avida.xcodeproj/project.pbxproj
===================================================================
--- branches/dkdev/Avida.xcodeproj/project.pbxproj	2007-02-26 01:09:12 UTC (rev 1369)
+++ branches/dkdev/Avida.xcodeproj/project.pbxproj	2007-02-26 01:09:53 UTC (rev 1370)
@@ -796,7 +796,7 @@
 		DCC315CF076253A5008F7A48 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
 		DCC315D0076253A5008F7A48 /* task_event_gen.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = task_event_gen.cc; sourceTree = "<group>"; };
 		DCC315D1076253A5008F7A48 /* task_event_gen.old.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = task_event_gen.old.cc; sourceTree = "<group>"; };
-		DCC3164D07626CF3008F7A48 /* avida */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = avida; sourceTree = BUILT_PRODUCTS_DIR; };
+		DCC3164D07626CF3008F7A48 /* avida */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = avida; sourceTree = BUILT_PRODUCTS_DIR; };
 		E03F28DA0B8A2840009966B8 /* cDeme.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cDeme.cc; sourceTree = "<group>"; };
 		E03F28DB0B8A2840009966B8 /* cDeme.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cDeme.h; sourceTree = "<group>"; };
 		E08178B90B3DCB9600B474B6 /* cTopology.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cTopology.h; sourceTree = "<group>"; };
@@ -1944,12 +1944,12 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				GCC_MODEL_CPU = G4;
+				HEADER_SEARCH_PATHS = "/usr/local/include/boost-1_33_1";
 				OTHER_LDFLAGS = (
 					"-multiply_defined",
 					suppress,
 				);
 				PRODUCT_NAME = avida;
-				USER_HEADER_SEARCH_PATHS = source/main;
 			};
 			name = Development;
 		};
@@ -1957,12 +1957,13 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				GCC_MODEL_CPU = G4;
+				HEADER_SEARCH_PATHS = "/usr/local/include/boost-1_33_1";
 				OTHER_LDFLAGS = (
 					"-multiply_defined",
 					suppress,
 				);
 				PRODUCT_NAME = avida;
-				USER_HEADER_SEARCH_PATHS = source/main;
+				USER_HEADER_SEARCH_PATHS = "";
 			};
 			name = "Deployment-G4";
 		};
@@ -2077,12 +2078,13 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				GCC_MODEL_CPU = G4;
+				HEADER_SEARCH_PATHS = "/usr/local/include/boost-1_33_1";
 				OTHER_LDFLAGS = (
 					"-multiply_defined",
 					suppress,
 				);
 				PRODUCT_NAME = avida;
-				USER_HEADER_SEARCH_PATHS = source/main;
+				USER_HEADER_SEARCH_PATHS = "";
 			};
 			name = "Deployment-G5";
 		};
@@ -2090,12 +2092,13 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				GCC_MODEL_CPU = G4;
+				HEADER_SEARCH_PATHS = "/usr/local/include/boost-1_33_1";
 				OTHER_LDFLAGS = (
 					"-multiply_defined",
 					suppress,
 				);
 				PRODUCT_NAME = avida;
-				USER_HEADER_SEARCH_PATHS = source/main;
+				USER_HEADER_SEARCH_PATHS = "";
 			};
 			name = Profile;
 		};
@@ -2204,12 +2207,13 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				GCC_MODEL_CPU = G4;
+				HEADER_SEARCH_PATHS = "/usr/local/include/boost-1_33_1";
 				OTHER_LDFLAGS = (
 					"-multiply_defined",
 					suppress,
 				);
 				PRODUCT_NAME = avida;
-				USER_HEADER_SEARCH_PATHS = source/main;
+				USER_HEADER_SEARCH_PATHS = "";
 			};
 			name = "Deployment-Universal";
 		};

Modified: branches/dkdev/source/actions/PopulationActions.cc
===================================================================
--- branches/dkdev/source/actions/PopulationActions.cc	2007-02-26 01:09:12 UTC (rev 1369)
+++ branches/dkdev/source/actions/PopulationActions.cc	2007-02-26 01:09:53 UTC (rev 1370)
@@ -842,6 +842,7 @@
     if (in_trigger == "all") m_rep_trigger = 0;
     else if (in_trigger == "full_deme") m_rep_trigger = 1;
     else if (in_trigger == "corners") m_rep_trigger = 2;
+    else if (in_trigger == "topo-connected") m_rep_trigger = 3;
     else {
       cString err("Unknown replication trigger '");
       err += in_trigger;

Modified: branches/dkdev/source/actions/PrintActions.cc
===================================================================
--- branches/dkdev/source/actions/PrintActions.cc	2007-02-26 01:09:12 UTC (rev 1369)
+++ branches/dkdev/source/actions/PrintActions.cc	2007-02-26 01:09:53 UTC (rev 1370)
@@ -64,6 +64,7 @@
 STATS_OUT_FILE(PrintInstructionData,   instruction.dat     );
 STATS_OUT_FILE(PrintGenotypeMap,       genotype_map.m      );
 STATS_OUT_FILE(PrintMarketData,		   market.dat		   );
+STATS_OUT_FILE(PrintTopologyData, topology.dat);
 
 #define POP_OUT_FILE(METHOD, DEFAULT)                                                     /*  1 */ \
 class cAction ## METHOD : public cAction {                                                /*  2 */ \
@@ -1475,6 +1476,7 @@
   action_lib->Register<cActionPrintInstructionData>("PrintInstructionData");
   action_lib->Register<cActionPrintGenotypeMap>("PrintGenotypeMap");
   action_lib->Register<cActionPrintMarketData>("PrintMarketData");
+  action_lib->Register<cActionPrintTopologyData>("PrintTopologyData");
   
   // Population Out Files
   action_lib->Register<cActionPrintPhenotypeData>("PrintPhenotypeData");

Modified: branches/dkdev/source/cpu/cHardwareCPU.cc
===================================================================
--- branches/dkdev/source/cpu/cHardwareCPU.cc	2007-02-26 01:09:12 UTC (rev 1369)
+++ branches/dkdev/source/cpu/cHardwareCPU.cc	2007-02-26 01:09:53 UTC (rev 1370)
@@ -31,9 +31,11 @@
 #include "cWorld.h"
 #include "cPopulation.h"
 #include "cPopulationCell.h"
+#include "cDeme.h"
 
 #include <limits.h>
 #include <fstream>
+#include <utility>
 
 using namespace std;
 
@@ -357,7 +359,10 @@
     // Messaging instructions
     cInstEntryCPU("send-msg", &cHardwareCPU::Inst_SendMessage),
     cInstEntryCPU("rtrv-msg", &cHardwareCPU::Inst_RetrieveMessage),
-    cInstEntryCPU("cell-id", &cHardwareCPU::Inst_CellID)
+    cInstEntryCPU("cell-id", &cHardwareCPU::Inst_CellID),
+    
+    // Construction instructions
+    cInstEntryCPU("cr-link", &cHardwareCPU::Inst_CreateLink)
   };
   
   const int n_size = sizeof(s_n_array)/sizeof(cNOPEntryCPU);
@@ -3418,6 +3423,50 @@
 */
 bool cHardwareCPU::Inst_CellID(cAvidaContext& ctx) {
 	const int reg_used = FindModifiedRegister(REG_BX);
-	GetRegister(reg_used) = m_world->GetPopulation().GetCell(organism->GetOrgInterface().GetCellID()).GetRandomCellID();
+	GetRegister(reg_used) = m_world->GetPopulation().GetCell(organism->GetCellID()).GetRandomCellID();
 	return true;
 }
+
+
+/*! Creates a link between cells, a form of distributed construction. 
+
+Going to try something a little different here, and put all the logic for the link
+creation in the instruction, rather than in an organism or deme.
+*/
+bool cHardwareCPU::Inst_CreateLink(cAvidaContext& ctx) {
+  if(organism->GetCellID()==-1) return false;
+  cPopulationCell& cell = m_world->GetPopulation().GetCell(organism->GetCellID());
+  cDeme& deme = m_world->GetPopulation().GetDeme(cell.GetDemeID());
+  cDeme::Network& network = deme.GetNetwork();
+  cDeme::CellVertexMap& cvMap = deme.GetCellVertexMap();
+
+  // What is the cell that we're trying to connect to?
+  int connectTo=0;
+  // First, do we have a label?
+  if(GetLabel().GetSize()) {
+    // Yes; get the cell to connect to from the register.
+    connectTo = GetRegister(FindModifiedRegister(REG_BX));
+    // Now, if this isn't a valid cell ID, fail.
+    if(!deme.IsCellID(connectTo)) return false;
+  } else {
+    // No; get the cell to connect to from our facing.
+    connectTo = cell.ConnectionList().GetFirst()->GetRandomCellID();
+  }
+
+  // Now, are this cell and the cell we're connecting to in the network?  If no,
+  // add them; if yes, then get a ref to the vertex descriptors.
+  cDeme::CellVertexMap::iterator u = cvMap.find(cell.GetRandomCellID());
+  if(u == cvMap.end()) {
+    // Add this cell to the network.
+    u = cvMap.insert(std::make_pair(cell.GetRandomCellID(), boost::add_vertex(network))).first;
+  }
+  cDeme::CellVertexMap::iterator v = cvMap.find(connectTo);
+  if(v == cvMap.end()) {
+    // Add the other cell to the network.
+    v = cvMap.insert(std::make_pair(connectTo, boost::add_vertex(network))).first;
+  }  
+
+  // Finally, add the edge.  We're done.
+  boost::add_edge(u->second, v->second, network);
+  return true;
+}

Modified: branches/dkdev/source/cpu/cHardwareCPU.h
===================================================================
--- branches/dkdev/source/cpu/cHardwareCPU.h	2007-02-26 01:09:12 UTC (rev 1369)
+++ branches/dkdev/source/cpu/cHardwareCPU.h	2007-02-26 01:09:53 UTC (rev 1370)
@@ -476,6 +476,9 @@
   bool Inst_SendMessage(cAvidaContext& ctx);
   bool Inst_RetrieveMessage(cAvidaContext& ctx);
   bool Inst_CellID(cAvidaContext& ctx);
+  
+  // Construction
+  bool Inst_CreateLink(cAvidaContext& ctx);
 };
 
 

Modified: branches/dkdev/source/main/cDeme.cc
===================================================================
--- branches/dkdev/source/main/cDeme.cc	2007-02-26 01:09:12 UTC (rev 1369)
+++ branches/dkdev/source/main/cDeme.cc	2007-02-26 01:09:53 UTC (rev 1370)
@@ -39,3 +39,9 @@
   return cell_ids[pos];
 }
 
+void cDeme::Reset() 
+{
+  birth_count = 0; 
+  m_network = Network();
+  m_cvMap = CellVertexMap();
+}

Modified: branches/dkdev/source/main/cDeme.h
===================================================================
--- branches/dkdev/source/main/cDeme.h	2007-02-26 01:09:12 UTC (rev 1369)
+++ branches/dkdev/source/main/cDeme.h	2007-02-26 01:09:53 UTC (rev 1370)
@@ -14,19 +14,18 @@
 #ifndef cDeme_h
 #define cDeme_h
 
-#ifndef tArray_h
+#include <boost/graph/adjacency_list.hpp>
+#include <map>
 #include "tArray.h"
-#endif
 
 
 class cDeme {
-private:
-  tArray<int> cell_ids;
-  int width;        // How wide is the deme?
-  int birth_count;  // How many organisms have been born into deme since reset?
-  int org_count;    // How many organisms are currently in the deme?
-
 public:
+  //! An ease-of-use typedef to support the distributed construction of a network.
+  typedef boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS> Network;
+  //! A map of cell IDs to vertex descriptors.
+  typedef std::map<int, Network::vertex_descriptor> CellVertexMap;
+  
   cDeme();
   ~cDeme();
 
@@ -39,7 +38,7 @@
   int GetWidth() const { return width; }
   int GetHeight() const { return cell_ids.GetSize() / width; }
 
-  void Reset() { birth_count = 0; }
+  void Reset();
   int GetBirthCount() const { return birth_count; }
   void IncBirthCount() { birth_count++; }
 
@@ -49,6 +48,22 @@
 
   bool IsEmpty() const { return org_count == 0; }
   bool IsFull() const { return org_count == cell_ids.GetSize(); }
+
+  //! Accessor for the network object associated with this deme.
+  Network& GetNetwork() { return m_network; }
+  //! Accessor for the cell-vertex map; contains cell ID -> vertex_descriptor entries.
+  CellVertexMap& GetCellVertexMap() { return m_cvMap; }
+  //! Returns true if cell_id is a cell ID in this deme, false otherwise.
+  bool IsCellID(int cell_id) { return false; }
+  
+private:
+  tArray<int> cell_ids;
+  int width;        // How wide is the deme?
+  int birth_count;  // How many organisms have been born into deme since reset?
+  int org_count;    // How many organisms are currently in the deme?
+
+  Network m_network; //!< The network associated with this deme.
+  CellVertexMap m_cvMap; //!< A map of cell IDs to vertex descriptors.
 };
 
 #endif

Modified: branches/dkdev/source/main/cPopulation.cc
===================================================================
--- branches/dkdev/source/main/cPopulation.cc	2007-02-26 01:09:12 UTC (rev 1369)
+++ branches/dkdev/source/main/cPopulation.cc	2007-02-26 01:09:53 UTC (rev 1370)
@@ -41,9 +41,7 @@
 
 #include <fstream>
 #include <vector>
-#include <algorithm>
-#include <set>
-#include <functional>
+#include <boost/graph/connected_components.hpp>
 
 #include <float.h>
 #include <math.h>
@@ -64,7 +62,7 @@
 {
   // How many demes are requested?
   int num_demes = m_world->GetConfig().NUM_DEMES.Get();    
-
+  
   // Error checking for demes vs. non-demes setup.
   const int birth_method = m_world->GetConfig().BIRTH_METHOD.Get();
   if(num_demes > 0) {
@@ -107,7 +105,7 @@
     deme_array[deme_id].Setup(deme_cells);
   }
   
-
+  
   // Setup the topology.
   // What we're doing here is chopping the cell_array up into num_demes pieces.
   // Note that having 0 demes (one population) is the same as having 1 deme.  Then
@@ -128,7 +126,7 @@
       }
       case nGeometry::CLIQUE: {
         build_clique(&cell_array.begin()[i], &cell_array.begin()[i+deme_size], 
-                   deme_size_x, deme_size_y);
+                     deme_size_x, deme_size_y);
         break;
       }
       default: {
@@ -155,7 +153,7 @@
                          res->GetOutflowY2() );
     m_world->GetStats().SetResourceName(i, res->GetName());
   }
- 
+  
   // Give stats information about the environment...
   const cTaskLib & task_lib = environment.GetTaskLib();
   for (int i = 0; i < task_lib.GetSize(); i++) {
@@ -167,7 +165,7 @@
   for (int i = 0; i < inst_set.GetSize(); i++) {
     m_world->GetStats().SetInstName(i, inst_set.GetName(i));
   }
-
+  
   // Load a clone if one is provided, otherwise setup start organism.
   if (m_world->GetConfig().CLONE_FILE.Get() == "-" || m_world->GetConfig().CLONE_FILE.Get() == "") {
     cGenome start_org = cInstUtil::LoadGenome(m_world->GetConfig().START_CREATURE.Get(), world->GetHardwareManager().GetInstSet());
@@ -209,7 +207,7 @@
   const int parent_id = parent_organism.GetOrgInterface().GetCellID();
   assert(parent_id >= 0 && parent_id < cell_array.GetSize());
   cPopulationCell& parent_cell = cell_array[parent_id];
-    
+  
   tArray<int> target_cells(child_array.GetSize());
   
   // Loop through choosing the later placement of each child in the population.
@@ -292,7 +290,7 @@
   
   if (target_organism->InjectHost(parent_cpu.GetLabel(), injected_code)) {
     cInjectGenotype* child_genotype = parent_genotype;
-
+    
     // If the parent genotype is not correct for the child, adjust it.
     if (parent_genotype == NULL || parent_genotype->GetGenome() != injected_code) {
       child_genotype = m_world->GetClassificationManager().GetInjectGenotype(injected_code, parent_genotype);
@@ -338,7 +336,7 @@
   // Update the contents of the target cell.
   KillOrganism(target_cell);
   target_cell.InsertOrganism(*in_organism);
-
+  
   // Setup the inputs in the target cell.
   environment.SetupInputs(ctx, target_cell.input_array);
   
@@ -379,18 +377,18 @@
   cOrganism* organism = in_cell.GetOrganism();
   cGenotype* genotype = organism->GetGenotype();
   m_world->GetStats().RecordDeath();
-
+  
   tList<tListNode<cSaleItem> >* sold_items = organism->GetSoldItems();
   if (sold_items)
   {
 	  tListIterator<tListNode<cSaleItem> > sold_it(*sold_items);
 	  tListNode<cSaleItem> * test_node;
-
+    
 	  while ( (test_node = sold_it.Next()) != NULL)
 	  {
-		tListIterator<cSaleItem> market_it(market[test_node->data->GetLabel()]);
-		market_it.Set(test_node);
-		delete market_it.Remove();
+      tListIterator<cSaleItem> market_it(market[test_node->data->GetLabel()]);
+      market_it.Set(test_node);
+      delete market_it.Remove();
 	  }
   }
   // Do the lineage handling
@@ -402,19 +400,19 @@
     deme_array[in_cell.GetDemeID()].DecOrgCount();
   }
   genotype->RemoveOrganism();
-
+  
   for (int i = 0; i < organism->GetNumParasites(); i++) {
     organism->GetParasite(i).RemoveParasite();
   }
-
+  
   // And clear it!
   in_cell.RemoveOrganism();
   if (!organism->IsRunning()) delete organism;
   else organism->GetPhenotype().SetToDelete();
-
+  
   // Alert the scheduler that this cell has a 0 merit.
   schedule->Adjust(in_cell.GetID(), cMerit(0));
-
+  
   // Update the archive (note: genotype adjustment may be defered)
   m_world->GetClassificationManager().AdjustGenotype(*genotype);
 }
@@ -469,7 +467,7 @@
 	// find list under appropriate label, labels more than 8 nops long are simply the same
 	// as a smaller label modded by the market size
 	//int pos = label % market.GetSize();
-
+  
 	//// id of genotype currently residing in cell that seller live(d) in compared to 
 	//// id of genotype of actual seller, if different than seller is dead, remove item from list
 	//while ( market[pos].GetSize() > 0 && 
@@ -479,15 +477,15 @@
 	//{
 	//	market[pos].Pop();
 	//}
-
+    
 	// create sale item
 	cSaleItem *new_item = new cSaleItem(data, label, sell_price, org_id, cell_id);
-
+  
 	// place into array by label, array is big enough for labels up to 8 nops long
 	tListNode<cSaleItem>* sell_node = market[label].PushRear(new_item);
 	tListNode<tListNode<cSaleItem> >* org_node = GetCell(cell_id).GetOrganism()->AddSoldItem(sell_node);
 	sell_node->data->SetNodePtr(org_node);
-
+  
 	//:7 for Kolby
 }
 
@@ -496,7 +494,7 @@
 	// find list under appropriate label, labels more than 8 nops long are simply the same
 	// as a smaller label modded by the market size
 	//int pos = label % market.GetSize();
-
+  
 	//// id of genotype currently residing in cell that seller live(d) in compared to 
 	//// id of genotype of actual seller, if different than seller is dead, remove item from list
 	//while ( market[pos].GetSize() > 0 && 
@@ -506,25 +504,25 @@
 	//{
 	//	market[pos].Pop();
 	//}
-
+    
 	// if there's nothing in the list don't bother with rest
 	if (market[label].GetSize() <= 0)
 		return 0;
-
+  
 	// if the sell price is higher than we're willing to pay no purchase made
 	if (market[label].GetFirst()->GetPrice() > buy_price)
 		return 0;
-
+  
 	// if the buy price is higher than buying org's current merit no purchase made
 	if (GetCell(cell_id).GetOrganism()->GetPhenotype().GetMerit().GetDouble() < buy_price)
 		return 0;
-
+  
 	// otherwise transaction should be completed!
 	cSaleItem* chosen = market[label].Pop();
 	tListIterator<tListNode<cSaleItem> > sold_it(*GetCell(chosen->GetCellID()).GetOrganism()->GetSoldItems());
 	sold_it.Set(chosen->GetNodePtr());
 	sold_it.Remove();
-
+  
 	// first update sellers merit
 	double cur_merit = GetCell(chosen->GetCellID()).GetOrganism()->GetPhenotype().GetMerit().GetDouble();
 	cur_merit += buy_price;
@@ -533,8 +531,8 @@
 	
 	// next remove sold item from list in market 
 	//market[pos].Remove(chosen);
-
-
+  
+  
 	// finally return recieve value, buyer merit will be updated if return a valid value here
 	int receive_value = chosen->GetData();
 	return receive_value;
@@ -547,12 +545,12 @@
  0: deme fitness = 1 (control, random deme selection)
  1: deme fitness = number of births since last competition (default) 
  2: deme fitness = average organism fitness at the current update (uses parent's fitness, so
-                     does not work with donations)
+                                                                   does not work with donations)
  3: deme fitness = average mutation rate at the current update
  4: deme fitness = strong rank selection on (parents) fitness (2^-deme fitness rank)
  5: deme fitness = average organism life (current, not parents) fitness (works with donations)
  6: deme fitness = strong rank selection on life (current, not parents) fitness
-*/
+ */
 //  For ease of use, each organism 
 // is setup as if it we just injected into the population.
 
@@ -571,7 +569,7 @@
     case 1:     // deme fitness = number of births
                 // Determine the scale for fitness by totaling births across demes.
       for (int deme_id = 0; deme_id < num_demes; deme_id++) {
-	double cur_fitness = (double) deme_array[deme_id].GetBirthCount();
+        double cur_fitness = (double) deme_array[deme_id].GetBirthCount();
         deme_fitness[deme_id] = cur_fitness;
         total_fitness += cur_fitness;
       }
@@ -579,12 +577,12 @@
     case 2:    // deme fitness = average organism fitness at the current update
       for (int deme_id = 0; deme_id < num_demes; deme_id++) {
         cDoubleSum single_deme_fitness;
-	const cDeme & cur_deme = deme_array[deme_id];
+        const cDeme & cur_deme = deme_array[deme_id];
         for (int i = 0; i < cur_deme.GetSize(); i++) {
           int cur_cell = cur_deme.GetCellID(i);
           if (cell_array[cur_cell].IsOccupied() == false) continue;
           cPhenotype & phenotype =
-	    GetCell(cur_cell).GetOrganism()->GetPhenotype();
+            GetCell(cur_cell).GetOrganism()->GetPhenotype();
           single_deme_fitness.Add(phenotype.GetFitness());
         } 
         deme_fitness[deme_id] = single_deme_fitness.Ave();
@@ -594,12 +592,12 @@
     case 3: 	// deme fitness = average mutation rate at the current update 
       for (int deme_id = 0; deme_id < num_demes; deme_id++) {
         cDoubleSum single_deme_div_type;
-	const cDeme & cur_deme = deme_array[deme_id];
+        const cDeme & cur_deme = deme_array[deme_id];
         for (int i = 0; i < cur_deme.GetSize(); i++) {
           int cur_cell = cur_deme.GetCellID(i);
           if (cell_array[cur_cell].IsOccupied() == false) continue;
           cPhenotype & phenotype =
-	    GetCell(cur_cell).GetOrganism()->GetPhenotype();
+            GetCell(cur_cell).GetOrganism()->GetPhenotype();
           assert(phenotype.GetDivType()>0);
           single_deme_div_type.Add(1/phenotype.GetDivType());
         }
@@ -612,7 +610,7 @@
     {      
       for (int deme_id = 0; deme_id < num_demes; deme_id++) {
         cDoubleSum single_deme_fitness;
-	const cDeme & cur_deme = deme_array[deme_id];
+        const cDeme & cur_deme = deme_array[deme_id];
         for (int i = 0; i < cur_deme.GetSize(); i++) {
           int cur_cell = cur_deme.GetCellID(i);
           if (cell_array[cur_cell].IsOccupied() == false) continue;
@@ -640,11 +638,11 @@
         total_fitness += deme_fitness[deme_id]; 
       } 
     }
-    break; 
-  case 5:    // deme fitness = average organism life fitness at the current update
-    for (int deme_id = 0; deme_id < num_demes; deme_id++) {
+      break; 
+    case 5:    // deme fitness = average organism life fitness at the current update
+      for (int deme_id = 0; deme_id < num_demes; deme_id++) {
         cDoubleSum single_deme_life_fitness;
-	const cDeme & cur_deme = deme_array[deme_id];
+        const cDeme & cur_deme = deme_array[deme_id];
         for (int i = 0; i < cur_deme.GetSize(); i++) {
           int cur_cell = cur_deme.GetCellID(i);
           if (cell_array[cur_cell].IsOccupied() == false) continue;
@@ -653,14 +651,14 @@
         }
         deme_fitness[deme_id] = single_deme_life_fitness.Ave();
         total_fitness += deme_fitness[deme_id];
-    }
-    break; 
-  case 6:     // deme fitness = 2^(-deme life fitness rank) (same as 4, but with life fitness)
+      }
+      break; 
+    case 6:     // deme fitness = 2^(-deme life fitness rank) (same as 4, but with life fitness)
     // first find all the deme fitness values ...
     {
       for (int deme_id = 0; deme_id < num_demes; deme_id++) {
         cDoubleSum single_deme_life_fitness;
-	const cDeme & cur_deme = deme_array[deme_id];
+        const cDeme & cur_deme = deme_array[deme_id];
         for (int i = 0; i < cur_deme.GetSize(); i++) {
           int cur_cell = cur_deme.GetCellID(i);
           if (cell_array[cur_cell].IsOccupied() == false) continue;
@@ -687,7 +685,7 @@
         }
         total_fitness += deme_fitness[deme_id];
       }
-    break;
+      break;
     }
   } 
   
@@ -736,7 +734,7 @@
     
     cDeme & from_deme = deme_array[from_deme_id];
     cDeme & to_deme   = deme_array[to_deme_id];
-
+    
     // Do the actual copy!
     for (int i = 0; i < from_deme.GetSize(); i++) {
       int from_cell_id = from_deme.GetCellID(i);
@@ -752,7 +750,7 @@
   for (int deme_id = 0; deme_id < num_demes; deme_id++) {
     if (is_init[deme_id] == true) continue;
     cDeme & cur_deme = deme_array[deme_id];
-
+    
     for (int i = 0; i < cur_deme.GetSize(); i++) {
       int cur_cell_id = cur_deme.GetCellID(i);
       if (cell_array[cur_cell_id].IsOccupied() == false) continue;
@@ -768,58 +766,73 @@
 
 
 /* Check if any demes have met the critera to be replicated and do so.
-   There are several bases this can be checked on:
+There are several bases this can be checked on:
 
-    0: 'all'       - ...all non-empty demes in the population.
-    1: 'full_deme' - ...demes that have been filled up.
-    2: 'corners'   - ...demes with upper left and lower right corners filled.
+0: 'all'       - ...all non-empty demes in the population.
+1: 'full_deme' - ...demes that have been filled up.
+2: 'corners'   - ...demes with upper left and lower right corners filled.
 */
 
 void cPopulation::ReplicateDemes(int rep_trigger)
 {
   // Determine which demes should be replicated.
   const int num_demes = GetNumDemes();
-
+  
   // Loop through all candidate demes...
   for (int deme_id = 0; deme_id < num_demes; deme_id++) {
     cDeme & source_deme = deme_array[deme_id];
-
+    
     // Test this deme to determine if it should be replicated.  If not,
     // continue on to the next deme.
     switch (rep_trigger) {
-    case 0:    // CASE: Replicate all non-empty demes...
+      case 0:    // CASE: Replicate all non-empty demes...
       // If this deme is empt, continue looping...
-      if (source_deme.IsEmpty()) continue;
-      break;
-    case 1:    // Replicate all full demes...
-      if (source_deme.IsFull() == false) continue;
-      break;
-    case 2:    // Replicate all demes with the corners filled in.
+        if (source_deme.IsEmpty()) continue;
+        break;
+      case 1:    // Replicate all full demes...
+        if (source_deme.IsFull() == false) continue;
+        break;
+      case 2:    // Replicate all demes with the corners filled in.
       {
-	// The first and last IDs represent the two corners.
-	const int id1 = source_deme.GetCellID(0);
-	const int id2 = source_deme.GetCellID(source_deme.GetSize() - 1);
-	if (cell_array[id1].IsOccupied() == false ||
-	    cell_array[id2].IsOccupied() == false) continue;
+        // The first and last IDs represent the two corners.
+        const int id1 = source_deme.GetCellID(0);
+        const int id2 = source_deme.GetCellID(source_deme.GetSize() - 1);
+        if (cell_array[id1].IsOccupied() == false ||
+            cell_array[id2].IsOccupied() == false) continue;
       }
-      break;
-    default:
-      cerr << "ERROR: Invalid replication trigger " << rep_trigger
-	   << " in cPopulation::ReplicateDemes()" << endl;
-      continue;
+        break;
+      case 3: {
+        // Checks to see if the topology that has been built by this deme:
+        // 1) Contains a vertex for all cells in the deme.
+        // 2) Is completely connected.
+        cDeme::Network& network = source_deme.GetNetwork();
+        if(boost::num_vertices(network) != (unsigned int)source_deme.GetSize()) continue;
+        std::vector<int> components(boost::num_vertices(network));
+        int num_components = boost::connected_components(network, &components[0]);
+        if(num_components > 1) continue;
+        
+        // Hm, ok, well we now have completely connected deme.  We should really do some
+        // stats tracking now.
+        m_world->GetStats().ConnectedTopology(network);
+        break;
+      }        
+      default:
+        cerr << "ERROR: Invalid replication trigger " << rep_trigger
+        << " in cPopulation::ReplicateDemes()" << endl;
+        continue;
     }
-
+    
     // -- If we made it this far, we should replicate this deme --
-
+    
     cRandom & random = m_world->GetRandom();
-
+    
     // Choose a random organism from this deme...
     int cell1_id = -1;
     const int deme1_size = source_deme.GetSize();
     while (cell1_id == -1 || cell_array[cell1_id].IsOccupied() == false) {
       cell1_id = source_deme.GetCellID(random.GetUInt(deme1_size));
     }
-
+    
     // Choose a random target deme to replicate to...
     int target_id = deme_id;
     while (target_id == deme_id) target_id = random.GetUInt(num_demes);
@@ -834,21 +847,25 @@
     // And do the replication into the central cell of the target deme...
     const int cell2_id = target_deme.GetCellID( deme2_size/2 );
     InjectClone( cell2_id, *(cell_array[cell1_id].GetOrganism()) );    
-
+    
     // Clear out the source deme to reset it
     for (int i = 0; i < deme1_size; i++) {
       KillOrganism(cell_array[ source_deme.GetCellID(i) ]);
     }
-
+    
     // Inject the target offspring back into the source ID.
     const int cell3_id = source_deme.GetCellID( deme1_size/2 );
     InjectClone( cell3_id, *(cell_array[cell2_id].GetOrganism()) );        
-
+    
     // Rotate both injected cells to face northwest.
     cell_array[cell2_id].Rotate(
-		cell_array[GridNeighbor(cell2_id, world_x, world_y, -1, -1)] );
+                                cell_array[GridNeighbor(cell2_id, world_x, world_y, -1, -1)] );
     cell_array[cell3_id].Rotate(
-		cell_array[GridNeighbor(cell3_id, world_x, world_y, -1, -1)] );
+                                cell_array[GridNeighbor(cell3_id, world_x, world_y, -1, -1)] );
+    
+    // And reset both demes, in case they have any cleanup work to do.
+    source_deme.Reset();
+    target_deme.Reset();
   }
 }
 
@@ -874,7 +891,7 @@
 {
   cDeme & deme1 = deme_array[deme1_id];
   cDeme & deme2 = deme_array[deme2_id];
-
+  
   for (int i = 0; i < deme1.GetSize(); i++) {
     int from_cell = deme1.GetCellID(i);
     int to_cell = deme2.GetCellID(i);
@@ -894,26 +911,26 @@
 {
   // Must spawn into a different deme.
   assert(deme1_id != deme2_id);
-
+  
   const int num_demes = deme_array.GetSize();
-
+  
   // If the second argument is a -1, choose a deme at random.
   cRandom & random = m_world->GetRandom();
   while (deme2_id == -1 || deme2_id == deme1_id) {
     deme2_id = random.GetUInt(num_demes);
   }
-
+  
   // Make sure we have all legal values...
   assert(deme1_id >= 0 && deme1_id < num_demes);
   assert(deme2_id >= 0 && deme2_id < num_demes);
-
+  
   // Find the demes that we're working with.
   cDeme & deme1 = deme_array[deme1_id];
   cDeme & deme2 = deme_array[deme2_id];
-
+  
   // Make sure that the deme we're copying from has at least 1 organism.
   assert(deme1.GetOrgCount() > 0);
-
+  
   // Determine the cell to copy from.
   int cell1_id = deme1.GetCellID( random.GetUInt(deme1.GetSize()) );
   while (cell_array[cell1_id].IsOccupied() == false) {
@@ -924,7 +941,7 @@
   for (int i = 0; i < deme2.GetSize(); i++) {
     KillOrganism(cell_array[ deme2.GetCellID(i) ]);
   }
-
+  
   // And do the spawning.
   int cell2_id = deme2.GetCellID( random.GetUInt(deme2.GetSize()) );
   InjectClone( cell2_id, *(cell_array[cell1_id].GetOrganism()) );    
@@ -1099,14 +1116,14 @@
   else if (birth_method == POSITION_CHILD_DEME_RANDOM) {
     const int deme_id = parent_cell.GetDemeID();
     const int deme_size = deme_array[deme_id].GetSize();
-
+    
     int out_pos = m_world->GetRandom().GetUInt(deme_size);
     int out_cell_id = deme_array[deme_id].GetCellID(out_pos);
     while (parent_ok == false && out_cell_id == parent_cell.GetID()) {
       out_pos = m_world->GetRandom().GetUInt(deme_size);
       out_cell_id = deme_array[deme_id].GetCellID(out_pos);
     }
-
+    
     deme_array[deme_id].IncBirthCount();
     return GetCell(out_cell_id);    
   }
@@ -1284,16 +1301,16 @@
     // Test what tasks this creatures has completed.
     for (int j=0; j < m_world->GetEnvironment().GetTaskLib().GetSize(); j++) {
       if (phenotype.GetCurTaskCount()[j] > 0)
-	  {
-		  stats.AddCurTask(j);
-		  stats.AddCurTaskQuality(j, phenotype.GetCurTaskQuality()[j]);
-	  }
+      {
+        stats.AddCurTask(j);
+        stats.AddCurTaskQuality(j, phenotype.GetCurTaskQuality()[j]);
+      }
       if (phenotype.GetLastTaskCount()[j] > 0)
-	  {
-		  stats.AddLastTask(j);
-		  stats.AddLastTaskQuality(j, phenotype.GetLastTaskQuality()[j]);
-		  stats.IncTaskExeCount(j, phenotype.GetLastTaskCount()[j]);
-	  } 
+      {
+        stats.AddLastTask(j);
+        stats.AddLastTaskQuality(j, phenotype.GetLastTaskQuality()[j]);
+        stats.IncTaskExeCount(j, phenotype.GetLastTaskCount()[j]);
+      } 
     }
     
     // Increment the counts for all qualities the organism has...
@@ -1312,7 +1329,7 @@
     
     // Increment the age of this organism.
     organism->GetPhenotype().IncAge();
-    }
+  }
   
   stats.SetBreedTrueCreatures(num_breed_true);
   stats.SetNumNoBirthCreatures(num_no_birth);
@@ -1334,7 +1351,7 @@
   stats.SetResources(resource_count.GetResources());
   stats.SetSpatialRes(resource_count.GetSpatialRes());
   stats.SetResourcesGeometry(resource_count.GetResourcesGeometry());
-  }
+}
 
 
 void cPopulation::UpdateGenotypeStats()
@@ -1707,11 +1724,11 @@
       }
     }
     cout << (*it).id_num << " "
-      << (*it).parent_id << " "
-      << (*it).genotype->GetParentID() << " "
-      << (*it).genotype->GetNumOffspringGenotypes() << " "
-      << (*it).num_cpus << " "
-      << (*it).genotype->GetNumOrganisms() << endl;
+    << (*it).parent_id << " "
+    << (*it).genotype->GetParentID() << " "
+    << (*it).genotype->GetNumOffspringGenotypes() << " "
+    << (*it).num_cpus << " "
+    << (*it).genotype->GetNumOrganisms() << endl;
     if (soup_full){
       cout << "cPopulation::LoadDumpFile: You are trying to load more organisms than there is space!" << endl;
       cout << "cPopulation::LoadDumpFile: Remaining organisms are ignored." << endl;
@@ -2051,7 +2068,7 @@
 void cPopulation::PrintPhenotypeData(const cString& filename)
 {
   set<int> ids;
-
+  
   for (int i = 0; i < cell_array.GetSize(); i++) {
     // Only look at cells with organisms in them.
     if (cell_array[i].IsOccupied() == false) continue;

Modified: branches/dkdev/source/main/cStats.cc
===================================================================
--- branches/dkdev/source/main/cStats.cc	2007-02-26 01:09:12 UTC (rev 1369)
+++ branches/dkdev/source/main/cStats.cc	2007-02-26 01:09:53 UTC (rev 1370)
@@ -848,3 +848,21 @@
 	num_bought = num_sold = num_used = num_own_used = 0;
 df.Endl();
 }
+
+void cStats::ConnectedTopology(cDeme::Network& network) {
+  ++m_topo_numReplications;
+  m_topo_numEdges.Add(boost::num_edges(network));
+}
+
+
+void cStats::PrintTopologyData(const cString& filename) {
+	cDataFile& df = m_world->GetDataFile(filename);
+	df.WriteComment( "Topology data\n" );
+	df.WriteTimeStamp();
+	df.Write(GetUpdate(), "update" );
+  df.Write(m_topo_numReplications, "Number of deme replications.");
+  df.Write(m_topo_numEdges.Average(), "Avg. number of edges on deme replication.");
+  m_topo_numReplications = 0;
+  m_topo_numEdges.Clear();
+  df.Endl();
+}

Modified: branches/dkdev/source/main/cStats.h
===================================================================
--- branches/dkdev/source/main/cStats.h	2007-02-26 01:09:12 UTC (rev 1369)
+++ branches/dkdev/source/main/cStats.h	2007-02-26 01:09:53 UTC (rev 1370)
@@ -40,6 +40,8 @@
 #include "nGeometry.h"
 #endif
 
+#include "cDeme.h"
+
 class cGenotype;
 class cInjectGenotype;
 class cWorld;
@@ -215,6 +217,9 @@
   int num_sold;
   int num_used;
   int num_own_used;
+  
+  int m_topo_numReplications; //!< Number of deme replications since the last stats output.
+  cDoubleSum m_topo_numEdges; //!< Average number of edges per deme upon replication.
 
   cStats(); // @not_implemented
   cStats(const cStats&); // @not_implemented
@@ -558,6 +563,11 @@
   void PrintInstructionData(const cString& filename);
   void PrintGenotypeMap(const cString& filename);
   void PrintMarketData(const cString& filename);
+  
+  // Topology
+  void ConnectedTopology(cDeme::Network& network);
+  void PrintTopologyData(const cString& filename);
+
 };
 
 




More information about the Avida-cvs mailing list