using System; using System.IO; using System.IO.Compression; using System.Linq; using System.Threading; using HeuristicLab.Algorithms.GrammaticalOptimization; using HeuristicLab.Analysis; using HeuristicLab.Common; using HeuristicLab.Data; using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; using HeuristicLab.Persistence.Default.Xml; using HeuristicLab.Problems.GrammaticalOptimization; namespace HeuristicLab.Algorithms.GeneticProgramming { public class OffspringSelectionGP : SolverBase, IGPSolver { public int PopulationSize { get; set; } public double MutationRate { 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 OffspringSelectionGP(ISymbolicExpressionTreeProblem problem, Random random, bool saveAlg = false) { this.problem = problem; this.random = random; // default parameter values PopulationSize = 100; 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 osga = new OffspringSelectionGeneticAlgorithm.OffspringSelectionGeneticAlgorithm(); // osga.Engine = new ParallelEngine.ParallelEngine(); osga.Engine = new SequentialEngine.SequentialEngine(); osga.ExceptionOccurred += (sender, args) => { Console.WriteLine(args.Value.Message); wh.Set(); }; osga.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) { osga.Stop(); } } }; osga.Problem = hlProblem; var mutator = (MultiSymbolicExpressionTreeManipulator)osga.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); } osga.Mutator = mutator; osga.Crossover = osga.CrossoverParameter.ValidValues.Single(op => op.Name == "SubtreeSwappingCrossover"); osga.Selector = osga.SelectorParameter.ValidValues.Single(op => op.Name == "GenderSpecificSelection"); var multiAnalzer = (MultiAnalyzer)osga.Analyzer; multiAnalzer.Operators.Add(new BestSymbolicExpressionTreeAnalyzer()); osga.PopulationSize.Value = PopulationSize; osga.MaximumGenerations.Value = 1000000; // some very large value (we stop based on evaluations) osga.MaximumSelectionPressure.Value = 1000000; osga.MaximumEvaluatedSolutions.Value = maxEvaluations; osga.MutationProbability.Value = MutationRate; osga.ComparisonFactorLowerBound.Value = 1.0; osga.ComparisonFactorUpperBound.Value = 1.0; osga.SuccessRatio.Value = 1.0; osga.SetSeedRandomly = new BoolValue(false); osga.Seed = new IntValue(random.Next()); osga.Prepare(); osga.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(osga, fullPath, CompressionLevel.Fastest); } } } } }