/// <summary> /// Run the genetic algorithm to train the neural network /// </summary> private void ExecuteTrainCommand() { this.ExecuteStopCommand(); // The background worker allows the GA to be run in a different thread BackgroundWorker backgroundWorker = new BackgroundWorker(); // Setup of the genetic algorithm LanderIndividualSettings landerIndividualSettings = new LanderIndividualSettings(); LanderIndividualFactory landerFactory = new LanderIndividualFactory(); GeneticAlgorithm.GeneticAlgorithm ga = new GeneticAlgorithm.GeneticAlgorithm(landerFactory); LanderIndividual best = null; int currentIteration = 0; // Set up the ga this.environment.Gravity = 2.0; this.environment.WindSpeed = 0.1; landerIndividualSettings.StartingFuel = 100; landerIndividualSettings.StartingHeight = 100; landerIndividualSettings.StartingHorizontal = 0; landerIndividualSettings.LanderEnvironment = this.environment; landerIndividualSettings.CrossoverAlgorithm = LanderIndividualSettings.CrossoverType.OnePoint; ga.SelectionType = GeneticAlgorithm.GeneticAlgorithm.SelectionTypes.Tournament; ga.TournamentSize = 4; ga.CrossoverProbability = 0; ga.MutationProbability = 1; ga.CalculationLimit = 60000; ga.ElitistCount = 4; ga.PopulationSize = 100; landerFactory.IndividualSettings = landerIndividualSettings; // This lambda function handles the iteration events from the ga. EventHandler<IterationEventArgs> handler = (sender, args) => { backgroundWorker.ReportProgress(0, args); }; // Set the work lambda function. backgroundWorker.DoWork += (sender, e) => { // Add the iteration event handler to report progress back to the main thread ga.IterationEvent += handler; // Run the ga best = (LanderIndividual)ga.Run(landerIndividualSettings); ga.IterationEvent -= handler; }; // Update the graph to show progress backgroundWorker.ProgressChanged += (sender, e) => { this.MinFitnessValues.Add(new Tuple<int, double>(currentIteration, ((IterationEventArgs)e.UserState).MinFitness)); this.MaxFitnessValues.Add(new Tuple<int, double>(currentIteration, ((IterationEventArgs)e.UserState).MaxFitness)); this.AvgFitnessValues.Add(new Tuple<int, double>(currentIteration, ((IterationEventArgs)e.UserState).AverageFitness)); currentIteration++; if (this.MinFitnessValues.Count > 600) { this.MinFitnessValues.Clear(); this.MaxFitnessValues.Clear(); this.AvgFitnessValues.Clear(); } }; backgroundWorker.RunWorkerCompleted += (sender, e) => { this.IsTraining = false; // Save the resulting neural network this.neuralNetwork = best.CurrentNeuralNetwork; Debug.WriteLine(this.neuralNetwork.ToString()); }; // Clear out previous chart data and run the background worker this.MinFitnessValues.Clear(); this.MaxFitnessValues.Clear(); this.AvgFitnessValues.Clear(); backgroundWorker.WorkerReportsProgress = true; this.IsTraining = true; backgroundWorker.RunWorkerAsync(); }
private static double Train(bool showOutput) { LanderIndividualSettings landerIndividualSettings = new LanderIndividualSettings(); LanderIndividualFactory landerFactory = new LanderIndividualFactory(); GeneticAlgorithm ga = new GeneticAlgorithm(landerFactory); LanderIndividual best = null; int currentIteration = 0; double bestfitness = 0; // Set up the ga LanderSimulator.Model.Environment environment = new LanderSimulator.Model.Environment(); environment.Gravity = 2.0; environment.WindSpeed = 0.1; landerIndividualSettings.StartingFuel = 100; landerIndividualSettings.StartingHeight = 100; landerIndividualSettings.StartingHorizontal = 0; landerIndividualSettings.LanderEnvironment = environment; landerIndividualSettings.CrossoverAlgorithm = LanderIndividualSettings.CrossoverType.Uniform; ga.SelectionType = GeneticAlgorithm.SelectionTypes.Tournament; ga.TournamentSize = 5; ga.CrossoverProbability = 0.98; ga.MutationProbability = 1; ga.CalculationLimit = 60000; ga.ElitistCount = 10; ga.PopulationSize = 500; landerFactory.IndividualSettings = landerIndividualSettings; // This lambda function handles the iteration events from the ga. EventHandler<IterationEventArgs> handler = (sender, args) => { if (showOutput) { Console.CursorLeft = 0; Console.Write("{0,4:g}{1,12:f3}{2,12:f3}{3,12:f3}{4,12:f3}{5,12:f3}{6,12:f3}", currentIteration, args.MinFitness, args.AverageFitness, args.MaxFitness, args.MinDifference, args.AverageDifference, args.MaxDifference); } currentIteration++; bestfitness = args.MinFitness; }; ga.IterationEvent += handler; if (showOutput) { Console.WriteLine("{0,4}{1,12}{2,12}{3,12}{4,12}{5,12}{6,12}", "", "Min Fit", "Avg Fit", "Max Fit", "Min Dif", "Avg Dif", "Max Dif"); } // Run the ga best = (LanderIndividual)ga.Run(landerIndividualSettings); Console.WriteLine(); neuralNetwork.SetAllWeights(best.CurrentNeuralNetwork.GetAllWeights()); ga.IterationEvent -= handler; return bestfitness; }