public override void Run(Configuration config) { //Setup log and solution this.log = new RandomLogSpecification(config.RandomSeed, config.MemoryLength, config.MaxTreeDepth); this.solution = new SolutionSpecification(); this.config = config; Dilemma best = null; //For the number of runs for(int run = 0; run < config.NumberOfRuns; run++) { //Initialize best fitness, so the first will always be a best fitness found double bestfitness = -1.0; //As long as we are under the number of fitness evals while(fitnessevals < config.NumberOfEvals) { //Make a new dilemma List<Dilemma> sequence = new List<Dilemma>(); //Initialize the memory InitializeUniformRandomMemory(config.MemoryLength); //Create a new tree Dilemma newdilemma = new Dilemma(); newdilemma.Tree = GenerateNewUniformRandomTree(config.MaxTreeDepth, 0); //Zero out total fitness for an average double totalfitness = 0.0; //Play IPD for(int i = 0; i < config.SequenceLength; i++) { //Add to total fitness totalfitness += (double)SingleFitnessCalculation(newdilemma.Tree.GetValue(memory), memory.ToArray()[memory.Count - 1][0]); //Place it in memory memory.Enqueue(new bool[2] { newdilemma.Tree.GetValue(memory), memory.ToArray()[memory.Count - 1][0] }); //If the memory is bigger than is allowed, pop the shiz. if(memory.Count > config.MemoryLength) { memory.Dequeue(); } } //Get the average totalfitness /= (double)config.SequenceLength; //Increment fitness evals because this is technically a fitness eval fitnessevals++; //Check for best and make a log entry if it is a new best. if(best == null || bestfitness < totalfitness) { best = newdilemma; bestfitness = totalfitness; ((RandomLogSpecification)log).AddEvaluation(fitnessevals, bestfitness); Console.WriteLine(fitnessevals + "\t" + bestfitness); } } } solution.PreOrderListing = best.Tree.PreOrderStringRealization; }
public static void Main(string[] args) { string filename; if(args.Length == 0) filename = "default.cfg"; else filename = args[0]; Configuration config = new Configuration(); try { config.loadFromFile(filename); } catch(Exception e) { Console.WriteLine("Main Exception: " + e.Message); return; } Console.WriteLine(config); //Do some reflection on types that can be used as an evolutionary program. var types = Assembly.GetExecutingAssembly().GetTypes(); GeneticProgram program = null; //I know there is a better way to do this. foreach(Type t in types) { foreach(Attribute a in t.GetCustomAttributes(typeof(ProgramAttribute), true)) { if(((ProgramAttribute)a).ProgramType == config.ProgramType) program = (GeneticProgram)Activator.CreateInstance(t); } } //Get a random number generator with a set seed, or a time seed. Random randomgenerator; if(config.RandomSeed < 0) randomgenerator = new Random(); else randomgenerator = new Random(config.RandomSeed); program.RandomGenerator = randomgenerator; program.Run(config); //Output stuff to files program.Log.writeToFile(config.LogFilePath); program.Solution.writeToFile(config.SolutionFilePath); }
public override void Run(Configuration config) { //Setup log and solution this.log = new COGPLogSpecification(config.RandomSeed, config.MemoryLength, config.MaxTreeDepth); this.solution = new SolutionSpecification(); this.config = config; Dilemma bestbestdilemma = null; for(int run=0; run < config.NumberOfRuns; run++) { //Initialize with ramped half and half List<Dilemma> population = RampedHalfAndHalfInitialization(config.PopulationSize, config.MemoryLength); //Initialize best fitness, so the first will always be a best fitness found Dilemma bestdilemma = null; fitnessevals = 0; int samefitnessiterations = 0; double averagefitness = 0.0; //Set up the initial population. for(int i = 0; i < population.Count; i++) { population[i].TimesPlayedIPD = 0; population[i].Fitness = 0.0; } //For each person in the population, pick a random other one from the population //to play IPD against. Do this populationsize * fitnesssamplingration times. //Record the fitness values for both. for(int i = 0; i < population.Count; i++) { Dilemma d1 = population[i]; for(int j = 0; j <= (int)(config.PopulationSize * config.FitnessSamplingRatio); j++) { int randomchoice = 0; do { randomchoice = RandomGenerator.Next(0, config.PopulationSize); } while(randomchoice == i); Dilemma d2 = population[randomchoice]; PlayIPD(ref d1, ref d2, config.SequenceLength, config.ParsimonyPressure, config.MaxTreeDepth, config.MemoryLength); d1.TimesPlayedIPD++; d2.TimesPlayedIPD++; } } //Normalize each dilemma's fitness in the population by //the times they played IPD. for(int i = 0; i < population.Count; i++) { population[i].Fitness /= population[i].TimesPlayedIPD; } bestdilemma = null; //Calculate average fitness, and check for best local dilemma for(int i = 0; i < population.Count; i++) { averagefitness += population[i].Fitness; if(bestdilemma == null || bestdilemma.Fitness < population[i].Fitness) { bestdilemma = population[i]; } } //Average fitness, and output to log. averagefitness /= (double)config.PopulationSize; ((COGPLogSpecification)log).AddEvaluation(run, fitnessevals, averagefitness, bestdilemma.Fitness); Console.WriteLine(fitnessevals + "\t" + averagefitness + "\t" + bestdilemma.Fitness); //As long as we are under the number of fitness evals while(fitnessevals < config.NumberOfEvals) { //Pick mutation or recombination int mutateorrecombine = RandomGenerator.Next(0, 2); List<Dilemma> newpopulation = new List<Dilemma>(); //Mutation if(mutateorrecombine == 0) { //Create lambda children for(int i = 0; i < config.ChildrenSize; i++) { //Select a random dilemma in the population to mutate. int randomselection = RandomGenerator.Next(0, population.Count); int mutateindex = 0; //Do the mutation. Dilemma newdil = SubTreeMutation(population[randomselection], RandomGenerator, config.MaxTreeDepth, out mutateindex); //Add it to the new population newpopulation.Add(newdil); } } //Recombination else { //Do this lambda times / 2 because each recombination creates two children. for(int i = 0; i < config.ChildrenSize / 2; i++) { //Fitness proportional or over selection if(config.UseFitnessProportionalForParent) { Dilemma parenta = FitnessProportionalSelection(population, this.RandomGenerator); Dilemma parentb = FitnessProportionalSelection(population, this.RandomGenerator); //Dummies. The out parameters are only used in tests. int indexa = 0; int indexb = 0; //Run recombination Dilemma[] newdils = SubTreeRecombination(parenta, parentb, RandomGenerator, out indexa, out indexb); //Add both new dilemmas to the new population newpopulation.Add(newdils[0]); newpopulation.Add(newdils[1]); } else if(config.UseOverSelectionForParent) { Dilemma parenta = OverSelection(population, config.PopulationSize, RandomGenerator); Dilemma parentb = OverSelection(population, config.PopulationSize, RandomGenerator); //Dummies. The out parameters are only used in tests. int indexa = 0; int indexb = 0; //run recombination Dilemma[] newdils = SubTreeRecombination(parenta, parentb, RandomGenerator, out indexa, out indexb); //Add both new dilemmas to the new population newpopulation.Add(newdils[0]); newpopulation.Add(newdils[1]); } else { throw new Exception("Parent selection algorithm not selected."); } } } //Use mu,lambda. Dump the old population, and only run IPD and survivor selection on new population. if(config.UseCommaForSelection) { //Truncation or k tournament //Reset each dilemma's times played IPD and fitness in the population. for(int i = 0; i < newpopulation.Count; i++) { newpopulation[i].TimesPlayedIPD = 0; newpopulation[i].Fitness = 0.0; } //For each one in the population play IPD against mu*fitnesssamplingration times. //Record it for both playing dilemmas. for(int i = 0; i < newpopulation.Count; i++) { Dilemma d1 = newpopulation[i]; for(int j = 0; j <= (int)(config.PopulationSize * config.FitnessSamplingRatio); j++) { int randomchoice = 0; do { randomchoice = RandomGenerator.Next(0, newpopulation.Count); } while(randomchoice == i); Dilemma d2 = newpopulation[randomchoice]; PlayIPD(ref d1, ref d2, config.SequenceLength, config.ParsimonyPressure, config.MaxTreeDepth, config.MemoryLength); d1.TimesPlayedIPD++; d2.TimesPlayedIPD++; } } //Normalize the fitnesses for(int i = 0; i < newpopulation.Count; i++) newpopulation[i].Fitness /= newpopulation[i].TimesPlayedIPD; //Use truncation to select the new population. if(config.UseTruncationForSurvival) { population = Truncation(newpopulation, config.PopulationSize); } //Use k tournament to select the new population. else if(config.UseKTournamentForSurvival) { population = KTournamentWithoutReplacement(newpopulation, config.PopulationSize, config.SurivivalTournamentSize, this.RandomGenerator); } } //Else use mu+lambda and do selection for the newpopulation and old population else if(config.UsePlusForSelection) { //add the new population to the normal population population.AddRange(newpopulation); //reset IPD related things for each one. for(int i = 0; i < population.Count; i++) { population[i].TimesPlayedIPD = 0; population[i].Fitness = 0.0; } //For each one in the population play IPD against mu*fitnesssamplingration times. //Record it for both playing dilemmas. for(int i = 0; i < population.Count; i++) { Dilemma d1 = population[i]; for(int j = 0; j <= (int)(config.PopulationSize * config.FitnessSamplingRatio); j++) { int randomchoice = 0; do { randomchoice = RandomGenerator.Next(0, config.PopulationSize); } while(randomchoice == i); Dilemma d2 = population[randomchoice]; PlayIPD(ref d1, ref d2, config.SequenceLength, config.ParsimonyPressure, config.MaxTreeDepth, config.MemoryLength); d1.TimesPlayedIPD++; d2.TimesPlayedIPD++; } } //Normalize the fitnesses for(int i = 0; i < population.Count; i++) population[i].Fitness /= population[i].TimesPlayedIPD; //Truncation or k tournament if(config.UseTruncationForSurvival) { //Run truncation on the population population = Truncation(population, config.PopulationSize); } else if(config.UseKTournamentForSurvival) { //Run ktournament on the population population = KTournamentWithoutReplacement(population, config.PopulationSize, config.SurivivalTournamentSize, this.RandomGenerator); } } //Clear out the new population. We no longer need it for this iteration newpopulation.Clear(); bool nochange = true; averagefitness = 0.0; bestdilemma = null; //Calculate average fitness, and check for best local dilemma for(int i = 0; i < population.Count; i++) { averagefitness += population[i].Fitness; if(bestdilemma == null || bestdilemma.Fitness < population[i].Fitness) { bestdilemma = population[i]; nochange = false; } } //Average averagefitness /= config.PopulationSize; //No change in best fitness if(nochange) samefitnessiterations++; else samefitnessiterations = 0; ((COGPLogSpecification)log).AddEvaluation(run, fitnessevals, averagefitness, bestdilemma.Fitness); Console.WriteLine(fitnessevals + "\t" + averagefitness + "\t" + bestdilemma.Fitness); //Check for termination convergence if(samefitnessiterations >= config.TerminationConvergence) break; } //Clear the population, and check for global best fitness. population.Clear(); if(bestbestdilemma == null || bestbestdilemma.Fitness < bestdilemma.Fitness) bestbestdilemma = bestdilemma; Dilemma winner = PlayIPDTitForTat(bestdilemma, config.SequenceLength, config.ParsimonyPressure, config.MaxTreeDepth, config.MemoryLength); ((COGPLogSpecification)log).AddAbsoluteFitness(winner.Fitness); bestdilemma = null; Thread.Sleep(2); } //Grab the global best dilemma bestbestdilemma.GenerateUniformRandomMemory(config.MemoryLength, RandomGenerator); solution.PreOrderListing = bestbestdilemma.Tree.PreOrderStringRealization; }
public abstract void Run(Configuration config);
public override void Run(Configuration config) { //Setup log and solution this.log = new GPLogSpecification(config.RandomSeed, config.MemoryLength, config.MaxTreeDepth); this.solution = new SolutionSpecification(); this.config = config; Dilemma bestbestdilemma = null; //For the number of runs for(int run = 0; run < config.NumberOfRuns; run++) { //Initialize with ramped half and half List<Dilemma> population = RampedHalfAndHalfInitialization(config.PopulationSize, config.MemoryLength); //Initialize best fitness, so the first will always be a best fitness found Dilemma bestdilemma = null; fitnessevals = 0; int samefitnessiterations = 0; double averagefitness = 0.0; //Set up the initial population. for(int i = 0; i < population.Count; i++) { population[i] = PlayIPD(population[i], config.SequenceLength, config.ParsimonyPressure, config.MaxTreeDepth, config.MemoryLength); averagefitness += population[i].Fitness; if(bestdilemma == null || bestdilemma.Fitness < population[i].Fitness) { bestdilemma = population[i]; } } //Average fitness, and output to log. averagefitness /= (double)config.PopulationSize; ((GPLogSpecification)log).AddEvaluation(run, fitnessevals, averagefitness, bestdilemma.Fitness); Console.WriteLine(fitnessevals + "\t" + averagefitness + "\t" + bestdilemma.Fitness); //As long as we are under the number of fitness evals while(fitnessevals < config.NumberOfEvals) { int mutateorrecombine = RandomGenerator.Next(0, 2); //Mutation if(mutateorrecombine == 0) { for(int i = 0; i < config.ChildrenSize; i++) { int randomselection = RandomGenerator.Next(0, population.Count); int mutateindex = 0; Dilemma newdil = SubTreeMutation(population[randomselection], RandomGenerator, config.MaxTreeDepth, out mutateindex); newdil = PlayIPD(population[randomselection], config.SequenceLength, config.ParsimonyPressure, config.MaxTreeDepth, config.MemoryLength); population.Add(newdil); } } //Recombination else { for(int i = 0; i < config.ChildrenSize; i++) { //Fitness proportional or over selection if(config.UseFitnessProportionalForParent) { Dilemma parenta = FitnessProportionalSelection(population, this.RandomGenerator); Dilemma parentb = FitnessProportionalSelection(population, this.RandomGenerator); //Dummies. The out parameters are only used in tests. int indexa = 0; int indexb = 0; Dilemma newdil = SubTreeRecombination(parenta, parentb, RandomGenerator, out indexa, out indexb); newdil = PlayIPD(newdil, config.SequenceLength, config.ParsimonyPressure, config.MaxTreeDepth, config.MemoryLength); population.Add(newdil); } else if(config.UseOverSelectionForParent) { Dilemma parenta = OverSelection(population, config.PopulationSize, RandomGenerator); Dilemma parentb = OverSelection(population, config.PopulationSize, RandomGenerator); //Dummies. The out parameters are only used in tests. int indexa = 0; int indexb = 0; Dilemma newdil = SubTreeRecombination(parenta, parentb, RandomGenerator, out indexa, out indexb); newdil = PlayIPD(newdil, config.SequenceLength, config.ParsimonyPressure, config.MaxTreeDepth, config.MemoryLength); population.Add(newdil); } else { throw new Exception("Parent selection algorithm not selected."); } } } //Truncation or k tournament if(config.UseTruncationForSurvival) { population = Truncation(population, config.PopulationSize); } else if(config.UseKTournamentForSurvival) { population = KTournamentWithoutReplacement(population, config.PopulationSize, config.SurivivalTournamentSize, this.RandomGenerator); } bool nochange = true; averagefitness = 0.0; //Calculate average fitness, and check for best local dilemma for(int i = 0; i < population.Count; i++) { Console.WriteLine(population[i]); averagefitness += population[i].Fitness; if(bestdilemma == null || bestdilemma.Fitness < population[i].Fitness) { bestdilemma = population[i]; nochange = false; } } //Average averagefitness /= config.PopulationSize; //No change in best fitness if(nochange) samefitnessiterations++; else samefitnessiterations = 0; ((GPLogSpecification)log).AddEvaluation(run, fitnessevals, averagefitness, bestdilemma.Fitness); Console.WriteLine(fitnessevals + "\t" + averagefitness + "\t" + bestdilemma.Fitness); //Check for termination convergence if(samefitnessiterations >= config.TerminationConvergence) break; } //Clear the population, and check for global best fitness. population.Clear(); if(bestbestdilemma == null || bestbestdilemma.Fitness < bestdilemma.Fitness) bestbestdilemma = bestdilemma; bestdilemma = null; } solution.PreOrderListing = bestbestdilemma.Tree.PreOrderStringRealization; }