#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.Linq; using CancellationToken = System.Threading.CancellationToken; using Variable = HeuristicLab.Core.Variable; namespace HeuristicLab.Algorithms.EvolvmentModelsOfModels { [Item("Evolvment Models Of Models Algorithm (EMM) ", "EMM implementation")] [Creatable(CreatableAttribute.Categories.PopulationBasedAlgorithms, Priority = 125)] [StorableType("AD23B21F-089A-4C6C-AD2E-1B01E7939CF5")] public class EMMAlgorithm : EvolvmentModelsOfModelsAlgorithmBase { public EMMAlgorithm() : base() { } protected EMMAlgorithm(EMMAlgorithm original, Cloner cloner) : base(original, cloner) { } public override IDeepCloneable Clone(Cloner cloner) { return new EMMAlgorithm(this, cloner); } [StorableConstructor] protected EMMAlgorithm(StorableConstructorFlag _) : base(_) { } protected override void Run(CancellationToken cancellationToken) { if (AlgorithmImplemetationType.Value == "Read") { Map.MapRead(RandomParameter.Value, trees, "Map.txt"); } else { Map.MapCreationPrepare(trees); Map.CreateMap(RandomParameter.Value, ClusterNumbersParameter.Value.Value); // Map.WriteMapToTxtFile(RandomParameter.Value); хайв этого не любит.. ворчит } ClusterNumbersShowParameter.Value.Value = Map.Map.Count; if (AlgorithmImplemetationType.Value == "OnlyMap") { globalScope = new Scope("Global Scope"); executionContext = new ExecutionContext(null, this, globalScope); } else { if (previousExecutionState != ExecutionState.Paused) { InitializeAlgorithm(cancellationToken); } if (!globalScope.Variables.ContainsKey("TreeModelMap")) globalScope.Variables.Add(new Variable("TreeModelMap", Map)); if (!globalScope.Variables.ContainsKey("Map")) globalScope.Variables.Add(new Variable("Map", Map)); EMMAlgorithmRun(cancellationToken); } } private void EMMAlgorithmRun(CancellationToken cancellationToken) { var bestSelector = new BestSelector(); bestSelector.CopySelected = new BoolValue(false); bestSelector.MaximizationParameter.ActualName = "Maximization"; bestSelector.NumberOfSelectedSubScopesParameter.ActualName = "Elites"; bestSelector.QualityParameter.ActualName = "Quality"; var maximumEvaluatedSolutions = MaximumEvaluatedSolutions.Value; var crossover = Crossover; var selector = Selector; 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); //if (Problem.ProblemData is IRegressionProblemData problemData) { // SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(Problem.SymbolicExpressionTreeInterpreter, (ISymbolicExpressionTree)childScope.Variables["SymbolicExpressionTree"].Value, problemData, problemData.TestIndices, true, 100 /*max iterration*/, true); //} ++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; } } if (Map is EMMSucsessMap) { var population = new Dictionary(); foreach (var individ in Population) { var tree = (ISymbolicExpressionTree)(((IScope)individ.Individual).Variables["SymbolicExpressionTree"].Value); population.Add(tree, individ.Qualities.Value); } Map.MapUpDate(population); population.Clear(); } //List A = new List(); //A.Add(new Scope ()); //A.Add(new SymbolicExpressionTree()); 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()) { globalScope.Variables.Add(new Variable(parameter.Name, parameter.Value)); } globalScope.Variables.Add(new Variable("Results", Results)); // make results available as a parameter for analyzers etc. var rand = RandomParameter.Value; if (SetSeedRandomly) Seed = RandomSeedGenerator.GetSeed(); rand.Reset(Seed); InitializePopulation(executionContext, cancellationToken, rand); EvaluatedSolutions = PopulationSize.Value; base.Initialize(cancellationToken); } private void InitializePopulation(ExecutionContext executionContext, CancellationToken cancellationToken, IRandom random) { Population = new List(); var evaluator = Problem.Evaluator; var creator = Problem.SolutionCreator; var parentScope = executionContext.Scope; //main scope for the next step work // first, create all individuals for (int i = 0; i < PopulationSize.Value; ++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()) { Map.NodeManipulationForInizializtion(random, node); } parentScope.SubScopes.Add(childScope); } // then, evaluate them and update qualities for (int i = 0; i < PopulationSize.Value; ++i) { var childScope = parentScope.SubScopes[i]; ExecuteOperation(executionContext, cancellationToken, executionContext.CreateChildOperation(evaluator, childScope)); Population.Add(new EMMSolution(childScope)); // Create solution and push individual inside. push solution to Population } } // next function was not tested in real work private void LocalDecent(ISymbolicDataAnalysisSingleObjectiveProblem problem, CancellationToken cancellationToken, IScope childScope) { int maxStepNumber = 100; var name = ((ISymbolicExpressionTreeCreator)Problem.SolutionCreator).SymbolicExpressionTreeParameter.ActualName; var tree = (ISymbolicExpressionTree)childScope.Variables[name].Value; var oldTree = tree.Clone(); ExecuteOperation(executionContext, cancellationToken, executionContext.CreateChildOperation(problem.Evaluator, childScope)); var rand = RandomParameter.Value; if (SetSeedRandomly) Seed = RandomSeedGenerator.GetSeed(); rand.Reset(Seed); while (maxStepNumber > 0) { maxStepNumber = TreeIterator(tree.Root, rand, cancellationToken, childScope, maxStepNumber); } } int TreeIterator(ISymbolicExpressionTreeNode a, IRandom rand, CancellationToken cancellationToken, IScope childScope, int maxStepNumber) { if (a is TreeModelTreeNode modelNode) { ModelChange(modelNode, rand, cancellationToken, childScope); maxStepNumber--; } if (a.Subtrees != null) { for (int i = 0; i < (a.Subtrees.Count()); i++) { TreeIterator(a.Subtrees.ToList()[i], rand, cancellationToken, childScope, maxStepNumber); } } return maxStepNumber; } void ModelChange(TreeModelTreeNode tree, IRandom rand, CancellationToken cancellationToken, IScope childScope) { int treeNumber = tree.TreeNumber; var oldSubTree = (ISymbolicExpressionTree)tree.Tree.Clone(); double oldQuality = ((DoubleValue)childScope.Variables["Quality"].Value).Value; int cluster; if (Map is EMMIslandMap map) cluster = map.ClusterNumber[treeNumber]; else cluster = treeNumber; int newTreeNumber = rand.Next(Map.Map[cluster].Count); tree.Tree = (ISymbolicExpressionTree)Map.ModelSet[newTreeNumber].Clone(); tree.Tree.Root.ShakeLocalParameters(rand, 1); var evaluator = Problem.Evaluator; ExecuteOperation(executionContext, cancellationToken, executionContext.CreateChildOperation(evaluator, childScope)); double currentQuality = ((DoubleValue)childScope.Variables["Quality"].Value).Value; if (oldQuality > currentQuality) { tree.Tree = (ISymbolicExpressionTree)oldSubTree.Clone(); ((DoubleValue)childScope.Variables["Quality"].Value).Value = oldQuality; } } } }