using System; using System.Linq; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Operators; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Problems.Programmable { [Item("Single-objective Improver", "Improves a solution by calling GetNeighbors and Evaluate of the corresponding problem definition.")] [StorableClass] public sealed class SingleObjectiveImprover : SingleSuccessorOperator, ISingleObjectiveImprovementOperator, IStochasticOperator { public IValueLookupParameter SolutionParameter { get { return new ValueLookupParameter("notused"); } } public ILookupParameter RandomParameter { get { return (ILookupParameter)Parameters["Random"]; } } public ILookupParameter ProblemDefinitionParameter { get { return (ILookupParameter)Parameters["ProblemDefinition"]; } } public ILookupParameter EncodingParameter { get { return (ILookupParameter)Parameters["Encoding"]; } } public ILookupParameter QualityParameter { get { return (ILookupParameter)Parameters["Quality"]; } } public ILookupParameter MaximizationParameter { get { return (ILookupParameter)Parameters["Maximization"]; } } public IValueLookupParameter ImprovementAttemptsParameter { get { return (IValueLookupParameter)Parameters["ImprovementAttempts"]; } } public IValueLookupParameter SampleSizeParameter { get { return (IValueLookupParameter)Parameters["SampleSize"]; } } public ILookupParameter LocalEvaluatedSolutionsParameter { get { return (ILookupParameter)Parameters["LocalEvaluatedSolutions"]; } } [StorableConstructor] private SingleObjectiveImprover(bool deserializing) : base(deserializing) { } private SingleObjectiveImprover(SingleObjectiveImprover original, Cloner cloner) : base(original, cloner) { } public SingleObjectiveImprover() { Parameters.Add(new LookupParameter("Random", "The random number generator to use.")); Parameters.Add(new LookupParameter("ProblemDefinition", "The host that holds the problem definition.")); Parameters.Add(new LookupParameter("Encoding", "An item that holds the problem's encoding.")); Parameters.Add(new LookupParameter("Quality", "The quality of the parameter vector.")); Parameters.Add(new LookupParameter("Maximization", "Whether the problem should be minimized or maximized.")); Parameters.Add(new ValueLookupParameter("ImprovementAttempts", "The number of improvement attempts the operator should perform.", new IntValue(100))); Parameters.Add(new ValueLookupParameter("SampleSize", "The number of samples to draw from the neighborhood function at maximum.", new IntValue(300))); Parameters.Add(new LookupParameter("LocalEvaluatedSolutions", "The number of solution evaluations that have been performed.")); } public override IDeepCloneable Clone(Cloner cloner) { return new SingleObjectiveImprover(this, cloner); } public override IOperation Apply() { var random = RandomParameter.ActualValue; var definition = ProblemDefinitionParameter.ActualValue; if (definition == null) throw new InvalidOperationException("Problem definition is null."); var encoding = EncodingParameter.ActualValue; var maximize = MaximizationParameter.ActualValue.Value; var maxAttempts = ImprovementAttemptsParameter.ActualValue.Value; var sampleSize = SampleSizeParameter.ActualValue.Value; var vector = Helper.Extract(ExecutionContext.Scope, encoding); var quality = QualityParameter.ActualValue == null ? definition.Evaluate(random, vector) : QualityParameter.ActualValue.Value; var count = 0; for (var i = 0; i < maxAttempts; i++) { Individual best = null; var bestQuality = quality; foreach (var neighbor in definition.GetNeighbors(random, vector).Take(sampleSize)) { var q = definition.Evaluate(random, neighbor); count++; if (maximize && bestQuality > q || !maximize && bestQuality < q) continue; best = neighbor; bestQuality = q; } if (best == null) break; vector = best; quality = bestQuality; } LocalEvaluatedSolutionsParameter.ActualValue = new IntValue(count); Helper.Write(ExecutionContext.Scope, vector); return base.Apply(); } } }