using System; using System.IO; using System.IO.Compression; using System.Linq; using System.Threading; using HeuristicLab.Algorithms.GrammaticalOptimization; using HeuristicLab.Common; using HeuristicLab.Data; using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; using HeuristicLab.Persistence.Default.Xml; using HeuristicLab.Problems.GrammaticalOptimization; using HeuristicLab.Selection; namespace HeuristicLab.Algorithms.GeneticProgramming { public class StandardGP : SolverBase, IGPSolver { public int PopulationSize { get; set; } public double MutationRate { get; set; } public int TournamentGroupSize { get; set; } public int MaxSolutionSize { get; set; } public int MaxSolutionDepth { get; set; } private readonly ISymbolicExpressionTreeProblem problem; private readonly Random random; private readonly bool saveAlg; public StandardGP(ISymbolicExpressionTreeProblem problem, Random random, bool saveAlg = false) { this.problem = problem; this.random = random; // default parameter values PopulationSize = 1000; TournamentGroupSize = 7; MutationRate = 0.15; MaxSolutionSize = 100; MaxSolutionDepth = 17; this.saveAlg = saveAlg; } public override void Run(int maxEvaluations) { var hlProblem = new GenericSymbExprProblem(problem); var onEvalLocker = new object(); hlProblem.MaximumSymbolicExpressionTreeLength.Value = MaxSolutionSize; hlProblem.MaximumSymbolicExpressionTreeDepth.Value = MaxSolutionDepth; using (var wh = new AutoResetEvent(false)) { var ga = new GeneticAlgorithm.GeneticAlgorithm(); ga.Engine = new ParallelEngine.ParallelEngine(); ga.ExceptionOccurred += (sender, args) => { Console.WriteLine(args.Value.Message); wh.Set(); }; ga.Stopped += (sender, args) => { wh.Set(); }; int numEvals = 0; hlProblem.Evaluator.SolutionEvaluated += (sentence, quality) => { // raise solution evaluated event for each GP solution, don't scale quality to 0..1 // need to synchronize in case we are using a parallel engine lock (onEvalLocker) { OnSolutionEvaluated(sentence, quality); // stop when maxEvals has been reached if (numEvals++ >= maxEvaluations) { ga.Stop(); } } }; ga.Problem = hlProblem; var mutator = (MultiSymbolicExpressionTreeManipulator)ga.MutatorParameter.ValidValues.Single(op => op.Name == "MultiSymbolicExpressionTreeManipulator"); foreach (var op in mutator.Operators) { if (op.Name == "ChangeNodeTypeManipulation" || op.Name == "ReplaceBranchManipulation") mutator.Operators.SetItemCheckedState(op, true); else mutator.Operators.SetItemCheckedState(op, false); } ga.Mutator = mutator; ga.Crossover = ga.CrossoverParameter.ValidValues.Single(op => op.Name == "SubtreeSwappingCrossover"); var selector = (TournamentSelector)ga.SelectorParameter.ValidValues.Single(op => op.Name == "TournamentSelector"); selector.GroupSizeParameter.Value = new IntValue(TournamentGroupSize); ga.Selector = selector; ga.PopulationSize.Value = PopulationSize; ga.MaximumGenerations.Value = 1000000; // very large value (we stop in the evaluate handler) ga.MutationProbability.Value = MutationRate; ga.SetSeedRandomly = new BoolValue(false); ga.Seed = new IntValue(random.Next()); ga.Prepare(); ga.Start(); wh.WaitOne(); if (saveAlg) { var path = @"C:\Users\P24581\Desktop"; var fileName = string.Format("osgp-{0}{1:D2}{2:D2}{3:D2}{4:D2}.hl", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute); var fullPath = Path.Combine(path, fileName); HeuristicLab.Persistence.Core.ConfigurationService.Instance.LoadSettings(); XmlGenerator.Serialize(ga, fullPath, CompressionLevel.Fastest); } } } } }