[Avida-SVN] r3273 - in development/source: actions cpu main

hjg at myxo.css.msu.edu hjg at myxo.css.msu.edu
Mon Jun 1 13:53:26 PDT 2009


Author: hjg
Date: 2009-06-01 16:53:23 -0400 (Mon, 01 Jun 2009)
New Revision: 3273

Modified:
   development/source/actions/PrintActions.cc
   development/source/cpu/cHardwareCPU.cc
   development/source/cpu/cHardwareCPU.h
   development/source/main/cPopulation.cc
   development/source/main/cPopulation.h
   development/source/main/cStats.cc
   development/source/main/cStats.h
   development/source/main/cTaskLib.cc
   development/source/main/cTaskLib.h
Log:
Group formation code. Essentially, the necessary instructions to let organisms form groups, where a group is defined as a set of organisms that share an opinion. Additionally, a task that rewards for groups of a desired size and stats tracking. 

Modified: development/source/actions/PrintActions.cc
===================================================================
--- development/source/actions/PrintActions.cc	2009-05-30 20:49:46 UTC (rev 3272)
+++ development/source/actions/PrintActions.cc	2009-06-01 20:53:23 UTC (rev 3273)
@@ -142,6 +142,10 @@
 STATS_OUT_FILE(PrintDirectReciprocityData,         reciprocity.dat);
 STATS_OUT_FILE(PrintStringMatchData,         stringmatch.dat);
 
+// group formation 
+STATS_OUT_FILE(PrintGroupsFormedData,         groupformation.dat);
+
+
 #define POP_OUT_FILE(METHOD, DEFAULT)                                                     /*  1 */ \
 class cAction ## METHOD : public cAction {                                                /*  2 */ \
 private:                                                                                  /*  3 */ \
@@ -3160,6 +3164,8 @@
   action_lib->Register<cActionPrintStringMatchData>("PrintStringMatchData");
 	action_lib->Register<cActionPrintShadedAltruists>("PrintShadedAltruists");
 
+	// Group Formation
+	action_lib->Register<cActionPrintGroupsFormedData>("PrintGroupsFormedData");
 	
   action_lib->Register<cActionSetVerbose>("VERBOSE");
 }

Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc	2009-05-30 20:49:46 UTC (rev 3272)
+++ development/source/cpu/cHardwareCPU.cc	2009-06-01 20:53:23 UTC (rev 3273)
@@ -567,8 +567,10 @@
 		tInstLibEntry<tMethod>("if-donor",  &cHardwareCPU::Inst_IfDonor, nInstFlag::STALL),
 		tInstLibEntry<tMethod>("prod-string",  &cHardwareCPU::Inst_ProduceString, nInstFlag::STALL),
 		
+		// Group formation instructions
+		tInstLibEntry<tMethod>("join-group", &cHardwareCPU::Inst_JoinGroup, nInstFlag::STALL),
+		tInstLibEntry<tMethod>("orgs-in-group", &cHardwareCPU::Inst_NumberOrgsInGroup, nInstFlag::STALL),
 		
-		
     // Must always be the last instruction in the array
     tInstLibEntry<tMethod>("NULL", &cHardwareCPU::Inst_Nop, 0, "True no-operation instruction: does nothing"),
   };
@@ -8919,3 +8921,41 @@
 	return true;
 }
 
+//! An organism joins a group by setting it opinion to the group id. 
+bool cHardwareCPU::Inst_JoinGroup(cAvidaContext& ctx)
+{
+	int opinion;
+	// Check if the org is currently part of a group
+	assert(m_organism != 0);
+  if(m_organism->HasOpinion()) {
+		opinion = m_organism->GetOpinion().first;
+		// subtract org from group
+		m_world->GetPopulation().LeaveGroup(opinion);
+  }
+	
+	
+	// Call the set opinion instruction, which does all the dirty work.
+	Inst_SetOpinion(ctx);
+	
+	// Add org to group count
+	opinion = m_organism->GetOpinion().first;	
+	m_world->GetPopulation().JoinGroup(opinion);
+	return true;
+}
+
+//! Gets the number of organisms in the current organism's group 
+//! and places the value in the ?CX? register
+bool cHardwareCPU::Inst_NumberOrgsInGroup(cAvidaContext& ctx)
+{
+	int num_orgs = 0;
+	assert(m_organism != 0);
+	const int num_org_reg = FindModifiedRegister(REG_CX);
+	int opinion;
+	
+  if(m_organism->HasOpinion()) {
+		opinion = m_organism->GetOpinion().first;
+		num_orgs = m_world->GetPopulation().NumberOfOrganismsInGroup(opinion);
+  }
+	GetRegister(num_org_reg) = num_orgs;
+	return true;
+}

Modified: development/source/cpu/cHardwareCPU.h
===================================================================
--- development/source/cpu/cHardwareCPU.h	2009-05-30 20:49:46 UTC (rev 3272)
+++ development/source/cpu/cHardwareCPU.h	2009-06-01 20:53:23 UTC (rev 3273)
@@ -846,8 +846,17 @@
   bool Inst_GetNeighborhood(cAvidaContext& ctx);
 	//! Test if the current neighborhood has changed from that in the organism's memory.
 	bool Inst_IfNeighborhoodChanged(cAvidaContext& ctx);
+
 	
+// -------- Group Formation Support --------
+public:
+	//! An organism joins a group by setting it opinion to the group id. 
+	bool Inst_JoinGroup(cAvidaContext& ctx);
+	//! Returns the number of organisms in the current organism's group
+	bool Inst_NumberOrgsInGroup(cAvidaContext& ctx);
+		
 	
+	
 };
 
 

Modified: development/source/main/cPopulation.cc
===================================================================
--- development/source/main/cPopulation.cc	2009-05-30 20:49:46 UTC (rev 3272)
+++ development/source/main/cPopulation.cc	2009-06-01 20:53:23 UTC (rev 3273)
@@ -5604,3 +5604,41 @@
   }
   
 }
+
+
+// Adds an organism to a group
+void  cPopulation::JoinGroup(int group_id)
+{
+	map<int,int>::iterator it;
+	it=m_groups.find(group_id);
+	if (it == m_groups.end()) {
+		m_groups[group_id] = 0;
+	}
+	m_groups[group_id]++;
+	
+}
+
+
+// Removes an organism from a group
+void  cPopulation::LeaveGroup(int group_id)
+{
+	map<int,int>::iterator it;
+	it=m_groups.find(group_id);
+	if (it != m_groups.end()) {
+		m_groups[group_id]--;
+	}
+
+}
+
+// Identifies the number of organisms in a group
+int  cPopulation::NumberOfOrganismsInGroup(int group_id)
+{
+	map<int,int>::iterator it;
+	it=m_groups.find(group_id);
+	int num_orgs = 0;
+	if (it != m_groups.end()) {
+		num_orgs = m_groups[group_id];
+	}
+	return num_orgs;	
+
+}

Modified: development/source/main/cPopulation.h
===================================================================
--- development/source/main/cPopulation.h	2009-05-30 20:49:46 UTC (rev 3272)
+++ development/source/main/cPopulation.h	2009-06-01 20:53:23 UTC (rev 3273)
@@ -27,7 +27,9 @@
 #define cPopulation_h
 
 #include <fstream>
+#include <map>
 
+
 #ifndef cBirthChamber_h
 #include "cBirthChamber.h"
 #endif
@@ -112,7 +114,11 @@
  
   // Outside interactions...
   bool sync_events;   // Do we need to sync up the event list with population?
+	
+	// Group formation information
+	std::map<int, int> m_groups; //<! Maps the group id to the number of orgs in the group
 
+
   ///////////////// Private Methods ////////////////////
   void BuildTimeSlicer(cChangeList* change_list); // Build the schedule object
 
@@ -326,7 +332,16 @@
   
   // Let users change environmental variables durning the run @BDB 22-Feb-2008
   void UpdateResourceCount(const int Verbosity);
-  
+	
+	// Adds an organism to a group
+	void JoinGroup(int group_id);
+	// Removes an organism from a group
+	void LeaveGroup(int group_id);
+	// Identifies the number of organisms in a group
+  int NumberOfOrganismsInGroup(int group_id);
+	// Get the group information
+	map<int, int> GetFormedGroups() { return m_groups; }
+	
 private:
   struct sTmpGenotype
   {

Modified: development/source/main/cStats.cc
===================================================================
--- development/source/main/cStats.cc	2009-05-30 20:49:46 UTC (rev 3272)
+++ development/source/main/cStats.cc	2009-06-01 20:53:23 UTC (rev 3273)
@@ -2544,4 +2544,40 @@
 	
 }
 
+/* 	
+ Print data regarding group formation.
+ */
+void cStats::PrintGroupsFormedData(const cString& filename)
+{
 
+	cDataFile& df = m_world->GetDataFile(filename);
+	df.WriteComment("The number of groups, average, max, and min number of orgs in groups");
+	
+	map<int,int> groups = m_world->GetPopulation().GetFormedGroups();
+	
+	map <int,int>::iterator itr;
+	double avg_size = 0.0;
+	double max_size = 0.0;
+	double min_size = 100000000000.0;
+	double active_groups = 0.0;
+	
+	for(itr = groups.begin();itr!=groups.end();itr++) {
+		avg_size += itr->second;
+		if (itr->second > max_size) max_size = itr->second;
+		if (itr->second < min_size) min_size = itr->second;
+		if (itr->second > 0) active_groups++;
+	}
+	
+	avg_size = avg_size / groups.size();
+	df.Write((double)groups.size(), "number of groups [num]");
+	df.Write(avg_size, "average size of groups [avg-size]");
+	df.Write(max_size, "max size of groups [max-size]");
+	df.Write(min_size, "min size of groups [min-size]");
+	df.Write(active_groups, "active groups [act-group]");
+	
+	
+	df.Endl();
+
+	
+}
+

Modified: development/source/main/cStats.h
===================================================================
--- development/source/main/cStats.h	2009-05-30 20:49:46 UTC (rev 3272)
+++ development/source/main/cStats.h	2009-06-01 20:53:23 UTC (rev 3273)
@@ -776,6 +776,7 @@
   void PrintCellVisitsData(const cString& filename);
   void PrintExtendedTimeData(const cString& filename);
   void PrintNumOrgsKilledData(const cString& filename);
+  void PrintGroupsFormedData(const cString& filename);
   
   // deme predicate stats
   void IncEventCount(int x, int y);

Modified: development/source/main/cTaskLib.cc
===================================================================
--- development/source/main/cTaskLib.cc	2009-05-30 20:49:46 UTC (rev 3272)
+++ development/source/main/cTaskLib.cc	2009-06-01 20:53:23 UTC (rev 3273)
@@ -438,6 +438,8 @@
   if (name == "sg_path_traversal")
     Load_SGPathTraversal(name, info, envreqs, errors);  
   
+	if (name == "form-group")
+    Load_FormSpatialGroup(name, info, envreqs, errors);
   
   // Make sure we have actually found a task  
   if (task_array.GetSize() == start_size) {
@@ -3383,3 +3385,35 @@
 	
 	return bonus; 
 }
+
+
+void cTaskLib::Load_FormSpatialGroup(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors)
+{
+	cArgSchema schema;
+  
+  // Integer Arguments
+  schema.AddEntry("group_size", 0, 1);
+  
+  cArgContainer* args = cArgContainer::Load(argstr, schema, errors);
+  if (args) NewTask(name, "FormSpatialGroups", &cTaskLib::Task_FormSpatialGroup, 0, args);
+}
+
+double cTaskLib::Task_FormSpatialGroup(cTaskContext& ctx) const
+{
+	int ideal_group_size = ctx.GetTaskEntry()->GetArguments().GetInt(0);
+	double reward = 0.0;
+	int group_id = 0; 
+	if (ctx.GetOrganism()->HasOpinion()) {
+		group_id = ctx.GetOrganism()->GetOpinion().first;
+	}
+	int orgs_in_group = m_world->GetPopulation().NumberOfOrganismsInGroup(group_id);
+	
+	if (orgs_in_group < ideal_group_size) {
+		reward = orgs_in_group*orgs_in_group;
+	} else {
+		reward = ideal_group_size*ideal_group_size;
+	}
+	reward = reward / ideal_group_size;
+	return reward;
+}
+

Modified: development/source/main/cTaskLib.h
===================================================================
--- development/source/main/cTaskLib.h	2009-05-30 20:49:46 UTC (rev 3272)
+++ development/source/main/cTaskLib.h	2009-06-01 20:53:23 UTC (rev 3273)
@@ -317,6 +317,10 @@
 	
 	// reputation
 	double Task_CreatePerfectStrings(cTaskContext& ctx) const; 
+	
+	// group formation 
+	void Load_FormSpatialGroup(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors);
+	double Task_FormSpatialGroup(cTaskContext& ctx) const; 
 };
 
 




More information about the Avida-cvs mailing list