#region License Information
/* HeuristicLab
* Copyright (C) 2002-2016 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using HeuristicLab.Algorithms.DataAnalysis;
using HeuristicLab.Algorithms.MemPR.Interfaces;
using HeuristicLab.Analysis;
using HeuristicLab.Common;
using HeuristicLab.Core;
using HeuristicLab.Data;
using HeuristicLab.Optimization;
using HeuristicLab.Parameters;
using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
using HeuristicLab.Problems.DataAnalysis;
using HeuristicLab.Random;
using ExecutionContext = HeuristicLab.Core.ExecutionContext;
namespace HeuristicLab.Algorithms.MemPR {
[Item("MemPRContext", "Abstract base class for MemPR contexts.")]
[StorableClass]
public abstract class MemPRPopulationContext : ParameterizedNamedItem,
IPopulationBasedHeuristicAlgorithmContext, ISolutionModelContext, IEvaluationServiceContext
where TProblem : class, IItem, ISingleObjectiveHeuristicOptimizationProblem
where TSolution : class, IItem
where TPopulationContext : MemPRPopulationContext
where TSolutionContext : MemPRSolutionContext {
private IExecutionContext parent;
public IExecutionContext Parent {
get { return parent; }
set { parent = value; }
}
[Storable]
private IScope scope;
public IScope Scope {
get { return scope; }
private set { scope = value; }
}
IKeyedItemCollection IExecutionContext.Parameters {
get { return Parameters; }
}
[Storable]
private IValueParameter problem;
public TProblem Problem {
get { return problem.Value; }
set { problem.Value = value; }
}
public bool Maximization {
get { return ((IValueParameter)Problem.MaximizationParameter).Value.Value; }
}
[Storable]
private IValueParameter initialized;
public bool Initialized {
get { return initialized.Value.Value; }
set { initialized.Value.Value = value; }
}
[Storable]
private IValueParameter iterations;
public int Iterations {
get { return iterations.Value.Value; }
set { iterations.Value.Value = value; }
}
[Storable]
private IValueParameter evaluatedSolutions;
public int EvaluatedSolutions {
get { return evaluatedSolutions.Value.Value; }
set { evaluatedSolutions.Value.Value = value; }
}
[Storable]
private IValueParameter bestQuality;
public double BestQuality {
get { return bestQuality.Value.Value; }
set { bestQuality.Value.Value = value; }
}
[Storable]
private IValueParameter bestSolution;
public TSolution BestSolution {
get { return bestSolution.Value; }
set { bestSolution.Value = value; }
}
[Storable]
private IValueParameter localSearchEvaluations;
public int LocalSearchEvaluations {
get { return localSearchEvaluations.Value.Value; }
set { localSearchEvaluations.Value.Value = value; }
}
[Storable]
private IValueParameter localOptimaLevel;
public double LocalOptimaLevel {
get { return localOptimaLevel.Value.Value; }
set { localOptimaLevel.Value.Value = value; }
}
[Storable]
private IValueParameter byBreeding;
public int ByBreeding {
get { return byBreeding.Value.Value; }
set { byBreeding.Value.Value = value; }
}
[Storable]
private IValueParameter byRelinking;
public int ByRelinking {
get { return byRelinking.Value.Value; }
set { byRelinking.Value.Value = value; }
}
[Storable]
private IValueParameter byDelinking;
public int ByDelinking {
get { return byDelinking.Value.Value; }
set { byDelinking.Value.Value = value; }
}
[Storable]
private IValueParameter bySampling;
public int BySampling {
get { return bySampling.Value.Value; }
set { bySampling.Value.Value = value; }
}
[Storable]
private IValueParameter byHillclimbing;
public int ByHillclimbing {
get { return byHillclimbing.Value.Value; }
set { byHillclimbing.Value.Value = value; }
}
[Storable]
private IValueParameter byAdaptivewalking;
public int ByAdaptivewalking {
get { return byAdaptivewalking.Value.Value; }
set { byAdaptivewalking.Value.Value = value; }
}
[Storable]
private IValueParameter random;
public IRandom Random {
get { return random.Value; }
set { random.Value = value; }
}
public IEnumerable> Population {
get { return scope.SubScopes.OfType>(); }
}
public void AddToPopulation(ISingleObjectiveSolutionScope solScope) {
scope.SubScopes.Add(solScope);
}
public void ReplaceAtPopulation(int index, ISingleObjectiveSolutionScope solScope) {
scope.SubScopes[index] = solScope;
}
public ISingleObjectiveSolutionScope AtPopulation(int index) {
return scope.SubScopes[index] as ISingleObjectiveSolutionScope;
}
public void SortPopulation() {
scope.SubScopes.Replace(scope.SubScopes.OfType>().OrderBy(x => Maximization ? -x.Fitness : x.Fitness).ToList());
}
public int PopulationCount {
get { return scope.SubScopes.Count; }
}
[Storable]
private IConfidenceRegressionModel breedingPerformanceModel;
public IConfidenceRegressionModel BreedingPerformanceModel {
get { return breedingPerformanceModel; }
}
[Storable]
private List> breedingStat;
public IEnumerable> BreedingStat {
get { return breedingStat; }
}
[Storable]
private IConfidenceRegressionModel relinkingPerformanceModel;
public IConfidenceRegressionModel RelinkingPerformanceModel {
get { return relinkingPerformanceModel; }
}
[Storable]
private List> relinkingStat;
public IEnumerable> RelinkingStat {
get { return relinkingStat; }
}
[Storable]
private IConfidenceRegressionModel delinkingPerformanceModel;
public IConfidenceRegressionModel DelinkingPerformanceModel {
get { return delinkingPerformanceModel; }
}
[Storable]
private List> delinkingStat;
public IEnumerable> DelinkingStat {
get { return delinkingStat; }
}
[Storable]
private IConfidenceRegressionModel samplingPerformanceModel;
public IConfidenceRegressionModel SamplingPerformanceModel {
get { return samplingPerformanceModel; }
}
[Storable]
private List> samplingStat;
public IEnumerable> SamplingStat {
get { return samplingStat; }
}
[Storable]
private IConfidenceRegressionModel hillclimbingPerformanceModel;
public IConfidenceRegressionModel HillclimbingPerformanceModel {
get { return hillclimbingPerformanceModel; }
}
[Storable]
private List> hillclimbingStat;
public IEnumerable> HillclimbingStat {
get { return hillclimbingStat; }
}
[Storable]
private IConfidenceRegressionModel adaptiveWalkPerformanceModel;
public IConfidenceRegressionModel AdaptiveWalkPerformanceModel {
get { return adaptiveWalkPerformanceModel; }
}
[Storable]
private List> adaptivewalkingStat;
public IEnumerable> AdaptivewalkingStat {
get { return adaptivewalkingStat; }
}
[Storable]
public ISolutionModel Model { get; set; }
[StorableConstructor]
protected MemPRPopulationContext(bool deserializing) : base(deserializing) { }
protected MemPRPopulationContext(MemPRPopulationContext original, Cloner cloner)
: base(original, cloner) {
scope = cloner.Clone(original.scope);
problem = cloner.Clone(original.problem);
initialized = cloner.Clone(original.initialized);
iterations = cloner.Clone(original.iterations);
evaluatedSolutions = cloner.Clone(original.evaluatedSolutions);
bestQuality = cloner.Clone(original.bestQuality);
bestSolution = cloner.Clone(original.bestSolution);
localSearchEvaluations = cloner.Clone(original.localSearchEvaluations);
localOptimaLevel = cloner.Clone(original.localOptimaLevel);
byBreeding = cloner.Clone(original.byBreeding);
byRelinking = cloner.Clone(original.byRelinking);
byDelinking = cloner.Clone(original.byDelinking);
bySampling = cloner.Clone(original.bySampling);
byHillclimbing = cloner.Clone(original.byHillclimbing);
byAdaptivewalking = cloner.Clone(original.byAdaptivewalking);
random = cloner.Clone(original.random);
breedingPerformanceModel = cloner.Clone(original.breedingPerformanceModel);
breedingStat = original.breedingStat.Select(x => Tuple.Create(x.Item1, x.Item2, x.Item3, x.Item4)).ToList();
relinkingPerformanceModel = cloner.Clone(original.relinkingPerformanceModel);
relinkingStat = original.relinkingStat.Select(x => Tuple.Create(x.Item1, x.Item2, x.Item3, x.Item4)).ToList();
delinkingPerformanceModel = cloner.Clone(original.delinkingPerformanceModel);
delinkingStat = original.delinkingStat.Select(x => Tuple.Create(x.Item1, x.Item2, x.Item3, x.Item4)).ToList();
samplingPerformanceModel = cloner.Clone(original.samplingPerformanceModel);
samplingStat = original.samplingStat.Select(x => Tuple.Create(x.Item1, x.Item2)).ToList();
hillclimbingPerformanceModel = cloner.Clone(original.hillclimbingPerformanceModel);
hillclimbingStat = original.hillclimbingStat.Select(x => Tuple.Create(x.Item1, x.Item2)).ToList();
adaptiveWalkPerformanceModel = cloner.Clone(original.adaptiveWalkPerformanceModel);
adaptivewalkingStat = original.adaptivewalkingStat.Select(x => Tuple.Create(x.Item1, x.Item2)).ToList();
Model = cloner.Clone(original.Model);
}
public MemPRPopulationContext() : this("MemPRContext") { }
public MemPRPopulationContext(string name) : base(name) {
scope = new Scope("Global");
Parameters.Add(problem = new ValueParameter("Problem"));
Parameters.Add(initialized = new ValueParameter("Initialized", new BoolValue(false)));
Parameters.Add(iterations = new ValueParameter("Iterations", new IntValue(0)));
Parameters.Add(evaluatedSolutions = new ValueParameter("EvaluatedSolutions", new IntValue(0)));
Parameters.Add(bestQuality = new ValueParameter("BestQuality", new DoubleValue(double.NaN)));
Parameters.Add(bestSolution = new ValueParameter("BestFoundSolution"));
Parameters.Add(localSearchEvaluations = new ValueParameter("LocalSearchEvaluations", new IntValue(0)));
Parameters.Add(localOptimaLevel = new ValueParameter("LocalOptimaLevel", new DoubleValue(0)));
Parameters.Add(byBreeding = new ValueParameter("ByBreeding", new IntValue(0)));
Parameters.Add(byRelinking = new ValueParameter("ByRelinking", new IntValue(0)));
Parameters.Add(byDelinking = new ValueParameter("ByDelinking", new IntValue(0)));
Parameters.Add(bySampling = new ValueParameter("BySampling", new IntValue(0)));
Parameters.Add(byHillclimbing = new ValueParameter("ByHillclimbing", new IntValue(0)));
Parameters.Add(byAdaptivewalking = new ValueParameter("ByAdaptivewalking", new IntValue(0)));
Parameters.Add(random = new ValueParameter("Random", new MersenneTwister()));
breedingStat = new List>();
relinkingStat = new List>();
delinkingStat = new List>();
samplingStat = new List>();
hillclimbingStat = new List>();
adaptivewalkingStat = new List>();
}
public abstract ISingleObjectiveSolutionScope ToScope(TSolution code, double fitness = double.NaN);
public virtual double Evaluate(TSolution solution, CancellationToken token) {
var solScope = ToScope(solution);
Evaluate(solScope, token);
return solScope.Fitness;
}
public virtual void Evaluate(ISingleObjectiveSolutionScope solScope, CancellationToken token) {
var pdef = Problem as ISingleObjectiveProblemDefinition;
if (pdef != null) {
var ind = new SingleEncodingIndividual(pdef.Encoding, solScope);
solScope.Fitness = pdef.Evaluate(ind, Random);
} else {
RunOperator(Problem.Evaluator, solScope, token);
}
}
public abstract TSolutionContext CreateSingleSolutionContext(ISingleObjectiveSolutionScope solution);
public void IncrementEvaluatedSolutions(int byEvaluations) {
if (byEvaluations < 0) throw new ArgumentException("Can only increment and not decrement evaluated solutions.");
EvaluatedSolutions += byEvaluations;
}
#region Breeding Performance
public void AddBreedingResult(ISingleObjectiveSolutionScope a, ISingleObjectiveSolutionScope b, double parentDist, ISingleObjectiveSolutionScope child) {
return;
if (IsBetter(a, b))
breedingStat.Add(Tuple.Create(a.Fitness, b.Fitness, parentDist, child.Fitness));
else breedingStat.Add(Tuple.Create(b.Fitness, a.Fitness, parentDist, child.Fitness));
if (breedingStat.Count % 10 == 0) RelearnBreedingPerformanceModel();
}
public void RelearnBreedingPerformanceModel() {
return;
breedingPerformanceModel = RunRegression(PrepareRegression(ToListRow(breedingStat)), breedingPerformanceModel).Model;
}
public bool BreedingSuited(ISingleObjectiveSolutionScope p1, ISingleObjectiveSolutionScope p2, double dist) {
return true;
if (breedingPerformanceModel == null) return true;
double minI1 = double.MaxValue, minI2 = double.MaxValue, maxI1 = double.MinValue, maxI2 = double.MinValue;
foreach (var d in BreedingStat) {
if (d.Item1 < minI1) minI1 = d.Item1;
if (d.Item1 > maxI1) maxI1 = d.Item1;
if (d.Item2 < minI2) minI2 = d.Item2;
if (d.Item2 > maxI2) maxI2 = d.Item2;
}
if (p1.Fitness < minI1 || p1.Fitness > maxI1 || p2.Fitness < minI2 || p2.Fitness > maxI2)
return true;
return Random.NextDouble() < ProbabilityAcceptAbsolutePerformanceModel(new List { p1.Fitness, p2.Fitness, dist }, breedingPerformanceModel);
}
#endregion
#region Relinking Performance
public void AddRelinkingResult(ISingleObjectiveSolutionScope a, ISingleObjectiveSolutionScope b, double parentDist, ISingleObjectiveSolutionScope child) {
return;
if (IsBetter(a, b))
relinkingStat.Add(Tuple.Create(a.Fitness, b.Fitness, parentDist, Maximization ? child.Fitness - a.Fitness : a.Fitness - child.Fitness));
else relinkingStat.Add(Tuple.Create(a.Fitness, b.Fitness, parentDist, Maximization ? child.Fitness - b.Fitness : b.Fitness - child.Fitness));
if (relinkingStat.Count % 10 == 0) RelearnRelinkingPerformanceModel();
}
public void RelearnRelinkingPerformanceModel() {
return;
relinkingPerformanceModel = RunRegression(PrepareRegression(ToListRow(relinkingStat)), relinkingPerformanceModel).Model;
}
public bool RelinkSuited(ISingleObjectiveSolutionScope p1, ISingleObjectiveSolutionScope p2, double dist) {
return true;
if (relinkingPerformanceModel == null) return true;
double minI1 = double.MaxValue, minI2 = double.MaxValue, maxI1 = double.MinValue, maxI2 = double.MinValue;
foreach (var d in RelinkingStat) {
if (d.Item1 < minI1) minI1 = d.Item1;
if (d.Item1 > maxI1) maxI1 = d.Item1;
if (d.Item2 < minI2) minI2 = d.Item2;
if (d.Item2 > maxI2) maxI2 = d.Item2;
}
if (p1.Fitness < minI1 || p1.Fitness > maxI1 || p2.Fitness < minI2 || p2.Fitness > maxI2)
return true;
if (IsBetter(p1, p2)) {
return Random.NextDouble() < ProbabilityAcceptRelativePerformanceModel(p1.Fitness, new List { p1.Fitness, p2.Fitness, dist }, relinkingPerformanceModel);
}
return Random.NextDouble() < ProbabilityAcceptRelativePerformanceModel(p2.Fitness, new List { p1.Fitness, p2.Fitness, dist }, relinkingPerformanceModel);
}
#endregion
#region Delinking Performance
public void AddDelinkingResult(ISingleObjectiveSolutionScope a, ISingleObjectiveSolutionScope b, double parentDist, ISingleObjectiveSolutionScope child) {
return;
if (IsBetter(a, b))
delinkingStat.Add(Tuple.Create(a.Fitness, b.Fitness, parentDist, Maximization ? child.Fitness - a.Fitness : a.Fitness - child.Fitness));
else delinkingStat.Add(Tuple.Create(a.Fitness, b.Fitness, parentDist, Maximization ? child.Fitness - b.Fitness : b.Fitness - child.Fitness));
if (delinkingStat.Count % 10 == 0) RelearnDelinkingPerformanceModel();
}
public void RelearnDelinkingPerformanceModel() {
return;
delinkingPerformanceModel = RunRegression(PrepareRegression(ToListRow(delinkingStat)), delinkingPerformanceModel).Model;
}
public bool DelinkSuited(ISingleObjectiveSolutionScope p1, ISingleObjectiveSolutionScope p2, double dist) {
return true;
if (delinkingPerformanceModel == null) return true;
double minI1 = double.MaxValue, minI2 = double.MaxValue, maxI1 = double.MinValue, maxI2 = double.MinValue;
foreach (var d in DelinkingStat) {
if (d.Item1 < minI1) minI1 = d.Item1;
if (d.Item1 > maxI1) maxI1 = d.Item1;
if (d.Item2 < minI2) minI2 = d.Item2;
if (d.Item2 > maxI2) maxI2 = d.Item2;
}
if (p1.Fitness < minI1 || p1.Fitness > maxI1 || p2.Fitness < minI2 || p2.Fitness > maxI2)
return true;
if (IsBetter(p1, p2)) {
return Random.NextDouble() < ProbabilityAcceptRelativePerformanceModel(p1.Fitness, new List { p1.Fitness, p2.Fitness, dist }, delinkingPerformanceModel);
}
return Random.NextDouble() < ProbabilityAcceptRelativePerformanceModel(p2.Fitness, new List { p1.Fitness, p2.Fitness, dist }, delinkingPerformanceModel);
}
#endregion
#region Sampling Performance
public void AddSamplingResult(ISingleObjectiveSolutionScope sample, double avgDist) {
return;
samplingStat.Add(Tuple.Create(avgDist, sample.Fitness));
if (samplingStat.Count % 10 == 0) RelearnSamplingPerformanceModel();
}
public void RelearnSamplingPerformanceModel() {
return;
samplingPerformanceModel = RunRegression(PrepareRegression(ToListRow(samplingStat)), samplingPerformanceModel).Model;
}
public bool SamplingSuited(double avgDist) {
return true;
if (samplingPerformanceModel == null) return true;
if (avgDist < samplingStat.Min(x => x.Item1) || avgDist > samplingStat.Max(x => x.Item1)) return true;
return Random.NextDouble() < ProbabilityAcceptAbsolutePerformanceModel(new List { avgDist }, samplingPerformanceModel);
}
#endregion
#region Hillclimbing Performance
public void AddHillclimbingResult(ISingleObjectiveSolutionScope input, ISingleObjectiveSolutionScope outcome) {
return;
hillclimbingStat.Add(Tuple.Create(input.Fitness, Maximization ? outcome.Fitness - input.Fitness : input.Fitness - outcome.Fitness));
if (hillclimbingStat.Count % 10 == 0) RelearnHillclimbingPerformanceModel();
}
public void RelearnHillclimbingPerformanceModel() {
return;
hillclimbingPerformanceModel = RunRegression(PrepareRegression(ToListRow(hillclimbingStat)), hillclimbingPerformanceModel).Model;
}
public bool HillclimbingSuited(double startingFitness) {
return true;
if (hillclimbingPerformanceModel == null) return true;
if (startingFitness < HillclimbingStat.Min(x => x.Item1) || startingFitness > HillclimbingStat.Max(x => x.Item1))
return true;
return Random.NextDouble() < ProbabilityAcceptRelativePerformanceModel(startingFitness, new List { startingFitness }, hillclimbingPerformanceModel);
}
#endregion
#region Adaptivewalking Performance
public void AddAdaptivewalkingResult(ISingleObjectiveSolutionScope input, ISingleObjectiveSolutionScope outcome) {
return;
adaptivewalkingStat.Add(Tuple.Create(input.Fitness, Maximization ? outcome.Fitness - input.Fitness : input.Fitness - outcome.Fitness));
if (adaptivewalkingStat.Count % 10 == 0) RelearnAdaptiveWalkPerformanceModel();
}
public void RelearnAdaptiveWalkPerformanceModel() {
return;
adaptiveWalkPerformanceModel = RunRegression(PrepareRegression(ToListRow(adaptivewalkingStat)), adaptiveWalkPerformanceModel).Model;
}
public bool AdaptivewalkingSuited(double startingFitness) {
return true;
if (adaptiveWalkPerformanceModel == null) return true;
if (startingFitness < AdaptivewalkingStat.Min(x => x.Item1) || startingFitness > AdaptivewalkingStat.Max(x => x.Item1))
return true;
return Random.NextDouble() < ProbabilityAcceptRelativePerformanceModel(startingFitness, new List { startingFitness }, adaptiveWalkPerformanceModel);
}
#endregion
public IConfidenceRegressionSolution GetSolution(IConfidenceRegressionModel model, IEnumerable> data) {
return new ConfidenceRegressionSolution(model, PrepareRegression(ToListRow(data.ToList())));
}
public IConfidenceRegressionSolution GetSolution(IConfidenceRegressionModel model, IEnumerable> data) {
return new ConfidenceRegressionSolution(model, PrepareRegression(ToListRow(data.ToList())));
}
public IConfidenceRegressionSolution GetSolution(IConfidenceRegressionModel model, IEnumerable> data) {
return new ConfidenceRegressionSolution(model, PrepareRegression(ToListRow(data.ToList())));
}
protected RegressionProblemData PrepareRegression(List> data) {
var columns = data.First().Select(y => new List()).ToList();
foreach (var next in data.Shuffle(Random)) {
for (var i = 0; i < next.Count; i++) {
columns[i].Add(next[i]);
}
}
var ds = new Dataset(columns.Select((v, i) => i < columns.Count - 1 ? "in" + i : "out").ToList(), columns);
var regPrb = new RegressionProblemData(ds, Enumerable.Range(0, columns.Count - 1).Select(x => "in" + x), "out") {
TrainingPartition = { Start = 0, End = Math.Min(50, data.Count) },
TestPartition = { Start = Math.Min(50, data.Count), End = data.Count }
};
return regPrb;
}
protected static IConfidenceRegressionSolution RunRegression(RegressionProblemData trainingData, IConfidenceRegressionModel baseLineModel = null) {
var targetValues = trainingData.Dataset.GetDoubleValues(trainingData.TargetVariable, trainingData.TrainingIndices).ToList();
var baseline = baseLineModel != null ? new ConfidenceRegressionSolution(baseLineModel, trainingData) : null;
var constantSolution = new ConfidenceRegressionSolution(new ConfidenceConstantModel(targetValues.Average(), targetValues.Variance(), trainingData.TargetVariable), trainingData);
var gpr = new GaussianProcessRegression { Problem = { ProblemData = trainingData } };
if (trainingData.InputVariables.CheckedItems.Any(x => alglib.pearsoncorr2(trainingData.Dataset.GetDoubleValues(x.Value.Value).ToArray(), trainingData.TargetVariableValues.ToArray()) > 0.8)) {
gpr.MeanFunction = new MeanZero();
var cov1 = new CovarianceSum();
cov1.Terms.Add(new CovarianceLinearArd());
cov1.Terms.Add(new CovarianceConst());
gpr.CovarianceFunction = cov1;
}
IConfidenceRegressionSolution solution = null;
var cnt = 0;
do {
ExecuteAlgorithm(gpr);
solution = (IConfidenceRegressionSolution)gpr.Results["Solution"].Value;
cnt++;
} while (cnt < 10 && (solution == null || solution.TrainingRSquared.IsAlmost(0)));
return GetBestRegressionSolution(constantSolution, baseline, solution);
}
private static IConfidenceRegressionSolution GetBestRegressionSolution(IConfidenceRegressionSolution constant, IConfidenceRegressionSolution baseline, IConfidenceRegressionSolution solution) {
if (baseline == null)
return constant.TrainingMeanAbsoluteError < solution.TrainingMeanAbsoluteError ? constant : solution;
double a, b, c;
if (constant.ProblemData.Dataset.Rows < 60) {
c = constant.TrainingMeanAbsoluteError;
b = baseline.TrainingMeanAbsoluteError;
a = solution.TrainingMeanAbsoluteError;
} else {
c = constant.TestMeanAbsoluteError;
b = baseline.TestMeanAbsoluteError;
a = solution.TestMeanAbsoluteError;
}
if (c < b && (c < a || b < a)) return constant;
if (b < c && (b < a || c < a)) return baseline;
return solution;
}
protected static void ExecuteAlgorithm(IAlgorithm algorithm) {
using (var evt = new AutoResetEvent(false)) {
EventHandler exeStateChanged = (o, args) => {
if (algorithm.ExecutionState != ExecutionState.Started)
evt.Set();
};
algorithm.ExecutionStateChanged += exeStateChanged;
if (algorithm.ExecutionState != ExecutionState.Prepared) {
algorithm.Prepare(true);
evt.WaitOne();
}
algorithm.Start();
evt.WaitOne();
algorithm.ExecutionStateChanged -= exeStateChanged;
}
}
private double ProbabilityAcceptAbsolutePerformanceModel(List inputs, IConfidenceRegressionModel model) {
var inputVariables = inputs.Select((v, i) => "in" + i);
var ds = new Dataset(inputVariables.Concat( new [] { "out" }), inputs.Select(x => new List { x }).Concat(new [] { new List { double.NaN } }));
var mean = model.GetEstimatedValues(ds, new[] { 0 }).Single();
var sdev = Math.Sqrt(model.GetEstimatedVariances(ds, new[] { 0 }).Single());
// calculate the fitness goal
var goal = Maximization ? Population.Min(x => x.Fitness) : Population.Max(x => x.Fitness);
var z = (goal - mean) / sdev;
// return the probability of achieving or surpassing that goal
var y = alglib.invnormaldistribution(z);
return Maximization ? 1.0 - y /* P(X >= z) */ : y; // P(X <= z)
}
private double ProbabilityAcceptRelativePerformanceModel(double basePerformance, List inputs, IConfidenceRegressionModel model) {
var inputVariables = inputs.Select((v, i) => "in" + i);
var ds = new Dataset(inputVariables.Concat(new[] { "out" }), inputs.Select(x => new List { x }).Concat(new[] { new List { double.NaN } }));
var mean = model.GetEstimatedValues(ds, new[] { 0 }).Single();
var sdev = Math.Sqrt(model.GetEstimatedVariances(ds, new[] { 0 }).Single());
// calculate the improvement goal
var goal = Maximization ? Population.Min(x => x.Fitness) - basePerformance : basePerformance - Population.Max(x => x.Fitness);
var z = (goal - mean) / sdev;
// return the probability of achieving or surpassing that goal
return 1.0 - alglib.invnormaldistribution(z); /* P(X >= z) */
}
private static List> ToListRow(List> rows) {
return rows.Select(x => new List { x.Item1, x.Item2 }).ToList();
}
private static List> ToListRow(List> rows) {
return rows.Select(x => new List { x.Item1, x.Item2, x.Item3 }).ToList();
}
private static List> ToListRow(List> rows) {
return rows.Select(x => new List { x.Item1, x.Item2, x.Item3, x.Item4 }).ToList();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsBetter(ISingleObjectiveSolutionScope a, ISingleObjectiveSolutionScope b) {
return IsBetter(a.Fitness, b.Fitness);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsBetter(double a, double b) {
return double.IsNaN(b) && !double.IsNaN(a)
|| Maximization && a > b
|| !Maximization && a < b;
}
#region IExecutionContext members
public IAtomicOperation CreateOperation(IOperator op) {
return new ExecutionContext(this, op, Scope);
}
public IAtomicOperation CreateOperation(IOperator op, IScope s) {
return new ExecutionContext(this, op, s);
}
public IAtomicOperation CreateChildOperation(IOperator op) {
return new ExecutionContext(this, op, Scope);
}
public IAtomicOperation CreateChildOperation(IOperator op, IScope s) {
return new ExecutionContext(this, op, s);
}
#endregion
#region Engine Helper
public void RunOperator(IOperator op, IScope scope, CancellationToken cancellationToken) {
var stack = new Stack();
stack.Push(CreateChildOperation(op, scope));
while (stack.Count > 0) {
cancellationToken.ThrowIfCancellationRequested();
var next = stack.Pop();
if (next is OperationCollection) {
var coll = (OperationCollection)next;
for (int i = coll.Count - 1; i >= 0; i--)
if (coll[i] != null) stack.Push(coll[i]);
} else if (next is IAtomicOperation) {
var operation = (IAtomicOperation)next;
try {
next = operation.Operator.Execute((IExecutionContext)operation, cancellationToken);
} catch (Exception ex) {
stack.Push(operation);
if (ex is OperationCanceledException) throw ex;
else throw new OperatorExecutionException(operation.Operator, ex);
}
if (next != null) stack.Push(next);
}
}
}
#endregion
}
[Item("SingleSolutionMemPRContext", "Abstract base class for single solution MemPR contexts.")]
[StorableClass]
public abstract class MemPRSolutionContext : ParameterizedNamedItem,
ISingleSolutionHeuristicAlgorithmContext, IEvaluationServiceContext
where TProblem : class, IItem, ISingleObjectiveHeuristicOptimizationProblem
where TSolution : class, IItem
where TContext : MemPRPopulationContext
where TSolutionContext : MemPRSolutionContext {
private TContext parent;
public IExecutionContext Parent {
get { return parent; }
set { throw new InvalidOperationException("Cannot set the parent of a single-solution context."); }
}
[Storable]
private ISingleObjectiveSolutionScope scope;
public IScope Scope {
get { return scope; }
}
IKeyedItemCollection IExecutionContext.Parameters {
get { return Parameters; }
}
public TProblem Problem {
get { return parent.Problem; }
}
public bool Maximization {
get { return parent.Maximization; }
}
public double BestQuality {
get { return parent.BestQuality; }
set { parent.BestQuality = value; }
}
public TSolution BestSolution {
get { return parent.BestSolution; }
set { parent.BestSolution = value; }
}
public IRandom Random {
get { return parent.Random; }
}
[Storable]
private IValueParameter evaluatedSolutions;
public int EvaluatedSolutions {
get { return evaluatedSolutions.Value.Value; }
set { evaluatedSolutions.Value.Value = value; }
}
[Storable]
private IValueParameter iterations;
public int Iterations {
get { return iterations.Value.Value; }
set { iterations.Value.Value = value; }
}
ISingleObjectiveSolutionScope ISingleSolutionHeuristicAlgorithmContext.Solution {
get { return scope; }
}
[StorableConstructor]
protected MemPRSolutionContext(bool deserializing) : base(deserializing) { }
protected MemPRSolutionContext(MemPRSolutionContext original, Cloner cloner)
: base(original, cloner) {
scope = cloner.Clone(original.scope);
evaluatedSolutions = cloner.Clone(original.evaluatedSolutions);
iterations = cloner.Clone(original.iterations);
}
public MemPRSolutionContext(TContext baseContext, ISingleObjectiveSolutionScope solution) {
parent = baseContext;
scope = solution;
Parameters.Add(evaluatedSolutions = new ValueParameter("EvaluatedSolutions", new IntValue(0)));
Parameters.Add(iterations = new ValueParameter("Iterations", new IntValue(0)));
}
public void IncrementEvaluatedSolutions(int byEvaluations) {
if (byEvaluations < 0) throw new ArgumentException("Can only increment and not decrement evaluated solutions.");
EvaluatedSolutions += byEvaluations;
}
public virtual double Evaluate(TSolution solution, CancellationToken token) {
return parent.Evaluate(solution, token);
}
public virtual void Evaluate(ISingleObjectiveSolutionScope solScope, CancellationToken token) {
parent.Evaluate(solScope, token);
}
#region IExecutionContext members
public IAtomicOperation CreateOperation(IOperator op) {
return new ExecutionContext(this, op, Scope);
}
public IAtomicOperation CreateOperation(IOperator op, IScope s) {
return new ExecutionContext(this, op, s);
}
public IAtomicOperation CreateChildOperation(IOperator op) {
return new ExecutionContext(this, op, Scope);
}
public IAtomicOperation CreateChildOperation(IOperator op, IScope s) {
return new ExecutionContext(this, op, s);
}
#endregion
}
}