using HeuristicLab.Operators; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using HeuristicLab.Common; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Parameters; using HeuristicLab.Optimization; using HeuristicLab.PluginInfrastructure; using HeuristicLab.Analysis; namespace HeuristicLab.Algorithms.SimulatedAnnealing { [Item("AdaptiveReheatingOperator", "Next to the annealing schedule, a hotter schedule is generated. Whenever a solution is accepted, the temperature of the annealing schedule is used. Whenever a solution is rejected, the temperature of the heating schedule is chosen.")] [StorableClass] public class AdaptiveReheatingOperator : SingleSuccessorOperator, IReheatingOperator { #region Strings private const string AnnealingOperatorName = "AnnealingOperator"; private const string LowerTemperatureName = "LowerTemperature"; private const string IterationsName = "Iterations"; private const string TemperatureStartIndexName = "TemperatureStartIndex"; private const string StartTemperatureName = "StartTemperature"; private const string EndTemperatureName = "EndTemperature"; private const string TemperatureName = "Temperature"; private const string MaximumIterationsName = "MaximumIterations"; private const string InitialTemperatureName = "InitialTemperature"; private const string IsAcceptedName = "IsAccepted"; private const string LastAcceptedQualityName = "LastAcceptedQuality"; private const string MoveQualityName = "MoveQuality"; private const string ReheatingOperatorName = "ReheatingOperator"; private const string OtherLowerTemperatureName = "OtherLowerTemperature"; #endregion #region Parameters public ILookupParameter TemperatureParameter { get { return (ILookupParameter)Parameters[TemperatureName]; } } public ILookupParameter LowerTemperatureParameter { get { return (ILookupParameter)Parameters[LowerTemperatureName]; } } public ILookupParameter StartTemperatureParameter { get { return (ILookupParameter)Parameters[StartTemperatureName]; } } public ILookupParameter EndTemperatureParameter { get { return (ILookupParameter)Parameters[EndTemperatureName]; } } public ILookupParameter TemperatureStartIndexParameter { get { return (ILookupParameter)Parameters[TemperatureStartIndexName]; } } public ILookupParameter IterationsParameter { get { return (ILookupParameter)Parameters[IterationsName]; } } public ILookupParameter AnnealingOperatorParameter { get { return (ILookupParameter)Parameters[AnnealingOperatorName]; } } public ILookupParameter MaximumIterationsParameter { get { return (ILookupParameter)Parameters[MaximumIterationsName]; } } public ILookupParameter IsAcceptedParameter { get { return (ILookupParameter)Parameters[IsAcceptedName]; } } public ILookupParameter MoveQualityParameter { get { return (ILookupParameter)Parameters[MoveQualityName]; } } public ILookupParameter LastAcceptedQualityParameter { get { return (ILookupParameter)Parameters[LastAcceptedQualityName]; } } public ILookupParameter InitialTemperatureParameter { get { return (ILookupParameter)Parameters[InitialTemperatureName]; } } private IConstrainedValueParameter ReheatingOperatorParameter { get { return (IConstrainedValueParameter)Parameters[ReheatingOperatorName]; } } private ValueParameter OtherLowerTemperatureParameter { get { return (ValueParameter)Parameters[OtherLowerTemperatureName]; } } #endregion public AdaptiveReheatingOperator() : base() { #region Create parameters Parameters.Add(new LookupParameter(TemperatureName, "The current temperature.")); Parameters.Add(new LookupParameter(LowerTemperatureName, "The lower bound of the temperature.")); Parameters.Add(new LookupParameter(IterationsName, "The number of iterations.")); Parameters.Add(new LookupParameter(AnnealingOperatorName, "The operator that cools the temperature.")); Parameters.Add(new LookupParameter(TemperatureStartIndexName, "The index where the annealing or heating was last changed.")); Parameters.Add(new LookupParameter(StartTemperatureName, "The temperature from which cooling should occur.")); Parameters.Add(new LookupParameter(EndTemperatureName, "The temperature to which should be cooled.")); Parameters.Add(new LookupParameter(MaximumIterationsName, "The maximum number of iterations which should be processed.")); Parameters.Add(new LookupParameter(IsAcceptedName, "Whether the move was accepted or not.")); Parameters.Add(new LookupParameter(LastAcceptedQualityName, "Quality of last accepted solution.")); Parameters.Add(new LookupParameter(MoveQualityName, "The value which represents the quality of a move.")); Parameters.Add(new LookupParameter(InitialTemperatureName, "The initial temperature.")); Parameters.Add(new ConstrainedValueParameter(ReheatingOperatorName, "The operator that reheats the temperature.")); Parameters.Add(new ValueParameter(OtherLowerTemperatureName, "The upper bound of the temperature of the heating schedule.", new DoubleValue(10))); foreach (var op in ApplicationManager.Manager.GetInstances().OrderBy(x => x.Name)) { ReheatingOperatorParameter.ValidValues.Add((IDiscreteDoubleValueModifier)op); } #endregion Parameterize(); } [StorableConstructor] protected AdaptiveReheatingOperator(bool deserializing) : base(deserializing) { } protected AdaptiveReheatingOperator(AdaptiveReheatingOperator original, Cloner cloner) : base(original, cloner) { } public override IDeepCloneable Clone(Cloner cloner) { return new AdaptiveReheatingOperator(this, cloner); } public void Parameterize() { foreach (var op in ReheatingOperatorParameter.ValidValues) { op.IndexParameter.ActualName = IterationsName; op.IndexParameter.Hidden = true; op.StartIndexParameter.Value = null; op.StartIndexParameter.ActualName = TemperatureStartIndexName; op.EndIndexParameter.ActualName = MaximumIterationsParameter.Name; op.ValueParameter.ActualName = TemperatureName; op.ValueParameter.Hidden = true; op.StartValueParameter.ActualName = StartTemperatureName; op.StartValueParameter.Hidden = true; op.EndValueParameter.Value = OtherLowerTemperatureParameter.Value; op.EndValueParameter.Hidden = true; } } public override IOperation Apply() { if(!IsAcceptedParameter.ActualValue.Value || LastAcceptedQualityParameter.ActualValue.Value.Equals(MoveQualityParameter.ActualValue.Value)) { return Heat(); }else { return Cool(); } } private IOperation Heat() { return new OperationCollection { ExecutionContext.CreateOperation(ReheatingOperatorParameter.Value), base.Apply() }; } private IOperation Cool() { return new OperationCollection { ExecutionContext.CreateOperation(AnnealingOperatorParameter.ActualValue), base.Apply() }; } } }