#region License Information /* HeuristicLab * Copyright (C) 2002-2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using HEAL.Attic; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; using HeuristicLab.Problems.DataAnalysis.Symbolic; using HeuristicLab.Random; using HeuristicLab.Selection; using System.Collections.Generic; using System.IO; using System.Linq; using CancellationToken = System.Threading.CancellationToken; using Variable = HeuristicLab.Core.Variable; namespace HeuristicLab.Algorithms.EvolvmentModelsOfModels { [Item("EvolvmentModelsOfModels Algorithm ", "EMM implementation")] [Creatable(CreatableAttribute.Categories.PopulationBasedAlgorithms, Priority = 125)] [StorableType("D02C50E5-8325-496F-8DEA-C23651756846")] public class EMMAlgorithm : EvolvmentModelsOfModelsAlgorithmBase { public EMMMapTreeModel Map { get; private set; } public EMMAlgorithm() : base() { } protected EMMAlgorithm(EMMAlgorithm original, Cloner cloner) : base(original, cloner) { if (original.Map != null) { Map = cloner.Clone(original.Map); } } public override IDeepCloneable Clone(Cloner cloner) { return new EMMAlgorithm(this, cloner); } [StorableConstructor] protected EMMAlgorithm(StorableConstructorFlag _) : base(_) { } protected override void Run(CancellationToken cancellationToken) { InfixExpressionParser parser = new InfixExpressionParser(); var trees = File.ReadAllLines(InputFileParameter.Value.Value).Select(parser.Parse); Map = new EMMMapTreeModel(RandomParameter.Value, trees, ClusterNumbersParameter.Value.Value); ClusterNumbersParameter.Value.Value = Map.K; if (previousExecutionState != ExecutionState.Paused) { InitializeAlgorithm(cancellationToken); } globalScope.Variables.Add(new Variable("TreeModelMap", Map)); EMMEvolutionaryAlgorithmRun(cancellationToken); } private void EMMEvolutionaryAlgorithmRun(CancellationToken cancellationToken) { var bestSelector = new BestSelector(); bestSelector.CopySelected = new BoolValue(false); bestSelector.MaximizationParameter.ActualName = "Maximization"; bestSelector.NumberOfSelectedSubScopesParameter.ActualName = "Elites"; bestSelector.QualityParameter.ActualName = "Quality"; var populationSize = PopulationSize.Value; var maximumEvaluatedSolutions = MaximumEvaluatedSolutions.Value; var crossover = Crossover; var selector = Selector; var groupSize = GroupSize.Value; var crossoverProbability = CrossoverProbability.Value; var mutator = Mutator; var mutationProbability = MutationProbability.Value; var evaluator = Problem.Evaluator; var analyzer = Analyzer; var rand = RandomParameter.Value; var elites = Elites.Value; // cancellation token for the inner operations which should not be immediately cancelled var innerToken = new CancellationToken(); while (evaluatedSolutions < maximumEvaluatedSolutions && !cancellationToken.IsCancellationRequested) { var op4 = executionContext.CreateChildOperation(bestSelector, executionContext.Scope); // select elites ExecuteOperation(executionContext, innerToken, op4); var remaining = executionContext.Scope.SubScopes.Single(x => x.Name == "Remaining"); executionContext.Scope.SubScopes.AddRange(remaining.SubScopes); var selected = executionContext.Scope.SubScopes.Single(x => x.Name == "Selected"); executionContext.Scope.SubScopes.AddRange(selected.SubScopes); population.Clear(); population.AddRange(selected.SubScopes.Select(x => new EMMSolution(x))); executionContext.Scope.SubScopes.Remove(remaining); executionContext.Scope.SubScopes.Remove(selected); var op = executionContext.CreateChildOperation(selector, executionContext.Scope);// select the rest of the population ExecuteOperation(executionContext, innerToken, op); remaining = executionContext.Scope.SubScopes.Single(x => x.Name == "Remaining"); selected = executionContext.Scope.SubScopes.Single(x => x.Name == "Selected"); for (int i = 0; i < selector.NumberOfSelectedSubScopesParameter.Value.Value; i += 2) { // crossover IScope childScope = null; if (rand.NextDouble() < crossoverProbability) { childScope = new Scope($"{i}+{i + 1}") { Parent = executionContext.Scope }; childScope.SubScopes.Add(selected.SubScopes[i]); childScope.SubScopes.Add(selected.SubScopes[i + 1]); var op1 = executionContext.CreateChildOperation(crossover, childScope); ExecuteOperation(executionContext, innerToken, op1); childScope.SubScopes.Clear(); } childScope = childScope ?? selected.SubScopes[i]; // mutation if (rand.NextDouble() < mutationProbability) { var op2 = executionContext.CreateChildOperation(mutator, childScope); ExecuteOperation(executionContext, innerToken, op2); } // evaluation if (childScope != null) { var op3 = executionContext.CreateChildOperation(evaluator, childScope); ExecuteOperation(executionContext, innerToken, op3); var qualities = (DoubleValue)childScope.Variables["Quality"].Value; var childSolution = new EMMSolution(childScope); // set child qualities childSolution.Qualities = qualities; ++evaluatedSolutions; population.Add(new EMMSolution(childScope)); } else {// no crossover or mutation were applied, a child was not produced, do nothing population.Add(new EMMSolution(selected.SubScopes[i])); } if (evaluatedSolutions >= maximumEvaluatedSolutions) { break; } } globalScope.SubScopes.Replace(population.Select(x => (IScope)x.Individual)); // run analyzer var analyze = executionContext.CreateChildOperation(analyzer, globalScope); ExecuteOperation(executionContext, innerToken, analyze); Results.AddOrUpdateResult("Evaluated Solutions", new IntValue(evaluatedSolutions)); } } protected void InitializeAlgorithm(CancellationToken cancellationToken) { globalScope = new Scope("Global Scope"); executionContext = new ExecutionContext(null, this, globalScope); // set the execution context for parameters to allow lookup foreach (var parameter in Problem.Parameters.OfType()) { // // we need all of these in order for the wiring of the operators to work globalScope.Variables.Add(new Core.Variable(parameter.Name, parameter.Value)); } globalScope.Variables.Add(new Core.Variable("Results", Results)); // make results available as a parameter for analyzers etc. var rand = RandomParameter.Value; if (SetSeedRandomly) Seed = RandomSeedGenerator.GetSeed(); rand.Reset(Seed); var populationSize = PopulationSize.Value; InitializePopulation(executionContext, cancellationToken, rand); // initialize data structures for map clustering var models = new ItemList(Map.ModelSet); var map = new ItemList>(); foreach (var list in Map.Map) { map.Add(new ItemList(list.Select(x => new IntValue(x)))); } var clusterNumber = new ItemList(Map.ClusterNumber.Select(x => new IntValue(x))); globalScope.Variables.Add(new Core.Variable("Models", models)); globalScope.Variables.Add(new Core.Variable("Map", map)); globalScope.Variables.Add(new Core.Variable("ClusterNumber", clusterNumber)); evaluatedSolutions = populationSize; base.Initialize(cancellationToken); } private void InitializePopulation(ExecutionContext executionContext, CancellationToken cancellationToken, IRandom random) { var creator = Problem.SolutionCreator; var evaluator = Problem.Evaluator; var populationSize = PopulationSize.Value; population = new List(populationSize); var parentScope = executionContext.Scope; //main scope for the next step work // first, create all individuals for (int i = 0; i < populationSize; ++i) { var childScope = new Scope(i.ToString()) { Parent = parentScope }; ExecuteOperation(executionContext, cancellationToken, executionContext.CreateChildOperation(creator, childScope)); var name = ((ISymbolicExpressionTreeCreator)creator).SymbolicExpressionTreeParameter.ActualName; var tree = (ISymbolicExpressionTree)childScope.Variables[name].Value; foreach (var node in tree.IterateNodesPostfix().OfType()) { node.Tree = Map.NewModelForInizializtion(random, out int cluster, out int treeNumber); node.Tree.Root.ShakeLocalParameters(random, 0.5); node.ClusterNumer = cluster; node.TreeNumber = treeNumber; } parentScope.SubScopes.Add(childScope); } // then, evaluate them and update qualities for (int i = 0; i < populationSize; ++i) { var childScope = parentScope.SubScopes[i]; ExecuteOperation(executionContext, cancellationToken, executionContext.CreateChildOperation(evaluator, childScope)); var qualities = (DoubleValue)childScope.Variables["Quality"].Value; var solution = new EMMSolution(childScope); // Create solution and push individual inside solution.Qualities = qualities; population.Add(solution); // push solution to population } } } }