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

beckma24 at myxo.css.msu.edu beckma24 at myxo.css.msu.edu
Fri May 22 08:05:34 PDT 2009


Author: beckma24
Date: 2009-05-22 11:05:34 -0400 (Fri, 22 May 2009)
New Revision: 3255

Modified:
   development/source/actions/PopulationActions.cc
   development/source/main/cDeme.cc
   development/source/main/cGenomeUtil.cc
   development/source/main/cGenomeUtil.h
Log:
Added actions TherapyStructuralNumInst and TherapyStructuralRatioDistBetweenNearest that apply to demes that are treatable

Modified: development/source/actions/PopulationActions.cc
===================================================================
--- development/source/actions/PopulationActions.cc	2009-05-21 20:11:27 UTC (rev 3254)
+++ development/source/actions/PopulationActions.cc	2009-05-22 15:05:34 UTC (rev 3255)
@@ -895,8 +895,145 @@
 	}
 };
 
+/*
+ Randomly removes organisms proportional to number of a specific instruction in genome.
+ Proportion is based on instruction count weight and exponent.
+ 
+ Parameters:
+ 1. instruction type (string) default: "nand"
+  - The type of instruction in question.
+ 2. weight value multiplied by instruction count
+ 3. exponent applied to weighted instruction count
+ */
+class cAction_TherapyStructuralNumInst : public cAction {
+private:
+	cString m_inst;
+	double m_exprWeight;
+	double m_exponent;
 
+public:
+	cAction_TherapyStructuralNumInst(cWorld* world, const cString& args) : cAction(world, args), m_inst("nand"), m_exprWeight(1.0), m_exponent(1.0)
+	{
+		cString largs(args);
+		if (largs.GetSize()) m_inst = largs.PopWord();
+		if (largs.GetSize()) m_exprWeight = largs.PopWord().AsDouble();
+		if (largs.GetSize()) m_exponent = largs.PopWord().AsDouble();
+	}
+	
+	static const cString GetDescription() { return "Arguments: [cString inst=nand] [double exprWeight=1.0] [double exponent=1.0(linear)]"; }
+	
+	void Process(cAvidaContext& ctx)
+	{
+		int totalkilled = 0;
+		
+		// for each deme in the population...
+		cPopulation& pop = m_world->GetPopulation();
+		const int numDemes = pop.GetNumDemes();
+		for (int demeCounter = 0; demeCounter < numDemes; ++demeCounter) {
+			cDeme& currentDeme = pop.GetDeme(demeCounter);
+			
+			// if deme treatable?
+			if(currentDeme.IsTreatableNow() == false)
+				continue; //No, go to next deme
+			
+			//Yes
+			for(int cellInDeme = 0; cellInDeme < currentDeme.GetSize(); ++cellInDeme) {
+				cPopulationCell& cell = currentDeme.GetCell(cellInDeme);
+
+				if (cell.IsOccupied() == false)
+					continue;
+				
+				// count the number of target instructions in the genome
+				int count = cGenomeUtil::CountInst(cell.GetOrganism()->GetGenome(), m_world->GetHardwareManager().GetInstSet().GetInst(m_inst));
+
+				double killprob = min(pow(m_exprWeight*count,m_exponent), 100.0)/100.0;
+				cout << count << " " << killprob << endl;
+
+				// decide if it should be killed or not, based on the kill probability
+				if (ctx.GetRandom().P(killprob)) {
+					m_world->GetPopulation().KillOrganism(cell);
+					totalkilled++;
+				}
+			}
+		// could keep track of the total number killed for statistics; in testing simply printed it out
+		// cout << "total killed = " << totalkilled << endl;
+		}
+	}
+};
+
+///////////////TOP
+
 /*
+ Randomly removes organisms proportional to minimum distance between two instances of the same instruction in its genome.
+ Proportion is based on instruction count weight and exponent.
+ 
+ Parameters:
+ 1. instruction type (string) default: "nand"
+ - The type of instruction in question.
+ 2. weight value multiplied by instruction count
+ 3. exponent applied to weighted instruction count
+ */
+class cAction_TherapyStructuralRatioDistBetweenNearest : public cAction {
+private:
+	cString m_inst;
+	double m_exprWeight;
+	double m_exponent;
+	
+public:
+	cAction_TherapyStructuralRatioDistBetweenNearest(cWorld* world, const cString& args) : cAction(world, args), m_inst("nand"), m_exprWeight(1.0), m_exponent(1.0)
+	{
+		cString largs(args);
+		if (largs.GetSize()) m_inst = largs.PopWord();
+		if (largs.GetSize()) m_exprWeight = largs.PopWord().AsDouble();
+		if (largs.GetSize()) m_exponent = largs.PopWord().AsDouble();
+	}
+	
+	static const cString GetDescription() { return "Arguments: [cString inst=nand] [double exprWeight=1.0] [double exponent=1.0(linear)]"; }
+	
+	void Process(cAvidaContext& ctx)
+	{
+		int totalkilled = 0;
+		// for each deme in the population...
+		cPopulation& pop = m_world->GetPopulation();
+		const int numDemes = pop.GetNumDemes();
+
+		for (int demeCounter = 0; demeCounter < numDemes; ++demeCounter) {
+			cDeme& currentDeme = pop.GetDeme(demeCounter);
+			
+			// if deme treatable?
+			if(currentDeme.IsTreatableNow() == false)
+				continue; //No, go to next deme
+			
+			//Yes
+			for(int cellInDeme = 0; cellInDeme < currentDeme.GetSize(); ++cellInDeme) {
+				cPopulationCell& cell = currentDeme.GetCell(cellInDeme);
+				
+				if (cell.IsOccupied() == false)
+					continue;
+				
+				// count the number of target instructions in the genome
+				const cGenome& genome = cell.GetOrganism()->GetGenome();
+				const double genomeSize = static_cast<double>(genome.GetSize());
+				int minDist = cGenomeUtil::MinDistBetween(genome, m_world->GetHardwareManager().GetInstSet().GetInst(m_inst));
+				
+				int ratioNumerator = min(genomeSize, pow(m_exprWeight*minDist, m_exponent));
+				double killprob = (genomeSize - static_cast<double>(ratioNumerator))/genomeSize;
+				// cout<<minDist << " " << killprob<<endl;
+				
+				// decide if it should be killed or not, based on the kill probability
+				if (ctx.GetRandom().P(killprob)) {
+					m_world->GetPopulation().KillOrganism(cell);
+					totalkilled++;
+				}
+			}
+		}
+		// could keep track of the total number killed for statistics; in testing simply printed it out
+		// cout << "total killed = " << totalkilled << endl;
+	}
+};
+
+
+/*
  In avida.cfg, when BASE_MERIT_METHOD is set to 6 (Merit prop. to num times MERIT_BONUS_INST is in genome), 
  the merit is incremented by MERIT_BONUS_EFFECT if MERIT_BONUS_EFFECT is positive and decremented by
  MERIT_BONUS_EFFECT if it is negative. For positive values the counting starts at 1, for negative values it starts
@@ -2972,6 +3109,12 @@
 	action_lib->Register<cActionKillInstLimit>("KillInstLimit");
 	action_lib->Register<cActionKillInstPair>("KillInstPair");
   action_lib->Register<cActionKillProb>("KillProb");
+	
+	// Theraputic deme actions
+	action_lib->Register<cAction_TherapyStructuralNumInst>("TherapyStructuralNumInst");
+	action_lib->Register<cAction_TherapyStructuralRatioDistBetweenNearest>("TherapyStructuralRatioDistBetweenNearest");
+	
+	
   action_lib->Register<cActionToggleRewardInstruction>("ToggleRewardInstruction");
   action_lib->Register<cActionToggleFitnessValley>("ToggleFitnessValley");
   action_lib->Register<cActionKillProb>("KillRate");

Modified: development/source/main/cDeme.cc
===================================================================
--- development/source/main/cDeme.cc	2009-05-21 20:11:27 UTC (rev 3254)
+++ development/source/main/cDeme.cc	2009-05-22 15:05:34 UTC (rev 3255)
@@ -860,6 +860,8 @@
 bool cDeme::IsTreatableAtAge(const int age) {
   
   if(isTreatable()) {
+		if(treatment_ages.size() == 0) // implies treatable every update
+			return true;
     set<int>::iterator it;
     it = treatment_ages.find(age);
     if(it != treatment_ages.end()) return true;  

Modified: development/source/main/cGenomeUtil.cc
===================================================================
--- development/source/main/cGenomeUtil.cc	2009-05-21 20:11:27 UTC (rev 3254)
+++ development/source/main/cGenomeUtil.cc	2009-05-22 15:05:34 UTC (rev 3255)
@@ -58,6 +58,43 @@
   return count;
 }
 
+// Returns minimum distance between two instance of inst respecting genome circularity.
+// If only one instance is found then lenght of genome is returned.
+int cGenomeUtil::MinDistBetween(const cGenome& genome, const cInstruction& inst) {
+	const int genomeSize = genome.GetSize();
+	int firstInstance(-1);
+	int secondInstance(-1);
+	int startIndex(0);
+	int minDist(genomeSize);
+
+	while(startIndex < genomeSize) {
+		firstInstance = FindInst(genome, inst, startIndex);
+		startIndex = firstInstance + 1;
+		
+		if(startIndex >= genomeSize)
+			return minDist;
+		
+		secondInstance = FindInst(genome, inst, startIndex);
+	
+		if(firstInstance != -1 and secondInstance != -1) {
+			minDist = min(min(secondInstance-firstInstance, firstInstance+genomeSize-secondInstance), minDist);
+		} else if(secondInstance != -1) {
+			secondInstance = FindInst(genome, inst, 0);
+			if(firstInstance == secondInstance)
+				return minDist;
+			else {
+				assert(secondInstance < firstInstance);
+				minDist = min(secondInstance+genomeSize-firstInstance, minDist);
+			}
+		} else {
+			return minDist;
+		}
+	}
+	assert(false);
+	return -1;
+}
+
+
 int cGenomeUtil::FindOverlap(const cGenome & gen1, const cGenome & gen2,
 			     int offset)
 {

Modified: development/source/main/cGenomeUtil.h
===================================================================
--- development/source/main/cGenomeUtil.h	2009-05-21 20:11:27 UTC (rev 3254)
+++ development/source/main/cGenomeUtil.h	2009-05-22 15:05:34 UTC (rev 3255)
@@ -43,6 +43,7 @@
   // ========= Detection =========
   static int FindInst(const cGenome& gen, const cInstruction& inst, int start_index = 0);
 	static int CountInst(const cGenome& gen, const cInstruction& inst);
+	static int MinDistBetween(const cGenome& gen, const cInstruction& inst);
 	
   static bool HasInst(const cGenome& gen, const cInstruction& inst)
   {




More information about the Avida-cvs mailing list