#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