//Randomly choose subtrees, and recombine. //This returns 2 new dilemma trees. public Dilemma[] SubTreeRecombination(Dilemma dilemmaA, Dilemma dilemmaB, Random randomgenerator, out int indexa, out int indexb) { Dilemma a1 = dilemmaA.Clone(); Dilemma b1 = dilemmaB.Clone(); Dilemma a2 = dilemmaA.Clone(); Dilemma b2 = dilemmaB.Clone(); int nodeaindex = randomgenerator.Next(0, a1.Tree.Size); int nodebindex = randomgenerator.Next(0, b1.Tree.Size); indexa = nodeaindex; indexb = nodebindex; if (nodeaindex == 0) a1 = b1; else { a1.Tree.ReplaceTree(nodeaindex, b1.Tree.RetrieveTree(nodebindex)); } if(nodebindex == 0) b2 = a2; else { b2.Tree.ReplaceTree(nodebindex, a2.Tree.RetrieveTree(nodeaindex)); } return new Dilemma[2] {a1.Clone(), b2.Clone()}; }
//Play the IPD, evaluating fitness for sequencelength - 2 * memorylength //Evaluate Tit For Tat. public Dilemma PlayIPDTitForTat(Dilemma dil, int sequencelength, double parsimonypressure, int maxtreedepth, int memorylength) { Dilemma dilemma = dil.Clone(); dilemma.Fitness = 0.0; dilemma.GenerateUniformRandomMemory(memorylength, RandomGenerator); for(int i = 0; i < sequencelength; i++) { if (i >= 2 * memorylength) { //Add to total fitness dilemma.Fitness += (double)SingleFitnessCalculation(dilemma.Tree.GetValue(dilemma.Memory), dilemma.Memory.ToArray()[dilemma.Memory.Count - 1][0]); } //Place it in memory dilemma.Memory.Enqueue(new bool[2] { dilemma.Tree.GetValue(dilemma.Memory), dilemma.Memory.ToArray()[dilemma.Memory.Count - 1][0] }); //If the memory is bigger than is allowed, pop the shiz. if(dilemma.Memory.Count > memorylength) { dilemma.Memory.Dequeue(); } } //ESSENTIALLY EVALUATING FITNESS dilemma.Fitness /= (sequencelength - 2 * memorylength); //Parsimony pressure: //Fitness = Fitness - Fitness * Parsimony Pressure * (Tree Size / Max Tree Size) //Parsimony Pressure is a double between 0.0 and 1.0. //Max tree size is 2^(Max Tree Depth) + 1 dilemma.Fitness -= (dilemma.Fitness * (parsimonypressure * (double)dilemma.Tree.Size / (double)((2<<maxtreedepth) + 1))); return dilemma; }
//10% chance of mutating a subtree. public Dilemma SubTreeMutation(Dilemma dilemma, Random randomgenerator, int maxtreedepth, out int mutateposition) { mutateposition = 0; int randomnumber; Dilemma newd = dilemma.Clone(); for(int i = 0; i < newd.Tree.Size; i++) { randomnumber = randomgenerator.Next(0, 10); OperatorTree tree; if(randomnumber == 5) { tree = newd.Tree.RetrieveTree(i); if (i == 0) newd.Tree = GenerateNewUniformRandomTreeGrow(maxtreedepth, 1, dilemma.Memory, randomgenerator, treepossibilities); else newd.Tree.ReplaceTree(i, GenerateNewUniformRandomTreeGrow(maxtreedepth, tree.Depth, dilemma.Memory, randomgenerator, treepossibilities)); mutateposition = i; break; } } return newd.Clone(); }
//Randomly choose subtrees, and recombine. public Dilemma SubTreeRecombination(Dilemma dilemmaA, Dilemma dilemmaB, Random randomgenerator, out int indexa, out int indexb) { Dilemma a = dilemmaA.Clone(); Dilemma b = dilemmaB.Clone(); int nodeaindex = randomgenerator.Next(0, a.Tree.Size); int nodebindex = randomgenerator.Next(0, b.Tree.Size); indexa = nodeaindex; indexb = nodebindex; if (nodeaindex == 0) a = b; else { a.Tree.ReplaceTree(nodeaindex, b.Tree.RetrieveTree(nodebindex)); } return a.Clone(); }