#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.Linq;
using HeuristicLab.Algorithms.EGO;
using HeuristicLab.Common;
using HeuristicLab.Core;
using HeuristicLab.Data;
using HeuristicLab.Encodings.RealVectorEncoding;
using HeuristicLab.Optimization;
using HeuristicLab.Parameters;
using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
namespace HeuristicLab.Algorithms.SAPBA {
[StorableClass]
public class InfillStrategy : StrategyBase {
#region Parameternames
public const string NoGenerationsParameterName = "Number of generations";
public const string NoIndividualsParameterName = "Number of individuals";
public const string InfillCriterionParameterName = "InfillCriterion";
#endregion
#region Paramterproperties
public IFixedValueParameter NoGenerationsParameter => Parameters[NoGenerationsParameterName] as IFixedValueParameter;
public IFixedValueParameter NoIndividualsParameter => Parameters[NoIndividualsParameterName] as IFixedValueParameter;
public IConstrainedValueParameter InfillCriterionParameter => Parameters[InfillCriterionParameterName] as IConstrainedValueParameter;
#endregion
#region Properties
public IntValue NoGenerations => NoGenerationsParameter.Value;
public IntValue NoIndividuals => NoIndividualsParameter.Value;
public IInfillCriterion InfillCriterion => InfillCriterionParameter.Value;
[Storable]
public int Generations;
#endregion
#region Constructors
[StorableConstructor]
protected InfillStrategy(bool deserializing) : base(deserializing) { }
[StorableHook(HookType.AfterDeserialization)]
private void AfterDeserialization() {
AttachListeners();
}
protected InfillStrategy(InfillStrategy original, Cloner cloner) : base(original, cloner) {
Generations = original.Generations;
AttachListeners();
}
public InfillStrategy() {
var critera = new ItemSet { new ExpectedImprovement(), new AugmentedExpectedImprovement(), new ExpectedQuality(), new ExpectedQuantileImprovement(), new MinimalQuantileCriterium(), new PluginExpectedImprovement() };
Parameters.Add(new FixedValueParameter(NoGenerationsParameterName, "The number of generations before a new model is constructed", new IntValue(3)));
Parameters.Add(new FixedValueParameter(NoIndividualsParameterName, "The number of individuals that are sampled each generation ", new IntValue(3)));
Parameters.Add(new ConstrainedValueParameter(InfillCriterionParameterName, "The infill criterion used to cheaply evaluate points.", critera, critera.First()));
AttachListeners();
}
public override IDeepCloneable Clone(Cloner cloner) {
return new InfillStrategy(this, cloner);
}
#endregion
protected override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, ResultCollection globalResults, IRandom random) { }
protected override void ProcessPopulation(Individual[] individuals, double[] qualities, IRandom random) {
if (RegressionSolution != null && Generations < NoGenerations.Value) Generations++;
else {
//Select NoIndividuals best samples
var samples = individuals
.Zip(qualities, (individual, d) => new Tuple(individual, d))
.OrderBy(t => Problem.Maximization ? -t.Item2 : t.Item2)
.Take(NoIndividuals.Value)
.Select(t => t.Item1.RealVector());
foreach (var indi in samples) EvaluateSample(indi, random);
BuildRegressionSolution(random);
Generations = 0;
}
}
protected override void Initialize() {
Generations = 0;
}
#region events
private void AttachListeners() {
ModelChanged += OnModelChanged;
}
private void OnModelChanged(object sender, EventArgs e) {
InfillCriterion.Encoding = Problem?.Encoding as RealVectorEncoding;
InfillCriterion.RegressionSolution = RegressionSolution;
InfillCriterion.ExpensiveMaximization = Problem?.Maximization ?? false;
if (RegressionSolution != null && InfillCriterion.Encoding != null)
InfillCriterion.Initialize();
}
#endregion
protected override double Estimate(RealVector point, IRandom random) {
return InfillCriterion.Maximization() != Maximization() ? -InfillCriterion.Evaluate(point) : InfillCriterion.Evaluate(point);
}
}
}