source: branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/ConsecutiveRejectionTemperatureResetOperator.cs @ 14702

Last change on this file since 14702 was 14702, checked in by jschiess, 5 years ago

#1836 SA reheating strategies: Added basic temperature reset strategy

File size: 9.0 KB
Line 
1using HeuristicLab.Operators;
2using System;
3using System.Collections.Generic;
4using System.Linq;
5using System.Text;
6using System.Threading.Tasks;
7using HeuristicLab.Common;
8using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
9using HeuristicLab.Core;
10using HeuristicLab.Data;
11using HeuristicLab.Parameters;
12using HeuristicLab.Optimization;
13using HeuristicLab.PluginInfrastructure;
14using HeuristicLab.Analysis;
15
16namespace HeuristicLab.Algorithms.SimulatedAnnealing
17{
18    [Item("ConsecutiveRejectionTemperatureResetOperator", "The operator resets the temperature to X when N consecutive solutions are rejected. X is calculated by BaseResetTemperature * (MultiplyWithEachReheat to the power of the current number of reheats).")]
19    [StorableClass]
20    public class ConsecutiveRejectionTemperatureResetOperator : SingleSuccessorOperator, IReheatingOperator
21    {
22        #region Strings
23        private const string AnnealingOperatorName = "AnnealingOperator";
24        private const string LowerTemperatureName = "LowerTemperature";
25        private const string IterationsName = "Iterations";
26        private const string TemperatureStartIndexName = "TemperatureStartIndex";
27        private const string StartTemperatureName = "StartTemperature";
28        private const string EndTemperatureName = "EndTemperature";
29        private const string TemperatureName = "Temperature";
30        private const string MaximumIterationsName = "MaximumIterations";
31
32        private const string ThresholdName = "Threshold";
33        private const string IsAcceptedName = "IsAccepted";
34        private const string AcceptanceMemoryName = "AcceptanceMemory";
35        private const string BaseResetTemperatureName = "BaseResetTemperature";
36        private const string MultiplyWithEachReheatName = "MultiplyWithEachReheat";
37        private const string ReheatCountName = "ReheatCount";
38        private const string MaximumNumberOfReheatsName = "MaximumNumberOfReheats";
39        #endregion
40
41        #region Parameters
42        private ValueParameter<DoubleValue> BaseResetTemperatureParameter
43        {
44            get { return (ValueParameter<DoubleValue>)Parameters[BaseResetTemperatureName]; }
45        }
46        private ValueParameter<DoubleValue> MultiplyWithEachReheatParameter
47        {
48            get { return (ValueParameter<DoubleValue>)Parameters[MultiplyWithEachReheatName]; }
49        }
50        public ILookupParameter<DoubleValue> TemperatureParameter
51        {
52            get { return (ILookupParameter<DoubleValue>)Parameters[TemperatureName]; }
53        }
54        public ILookupParameter<DoubleValue> LowerTemperatureParameter
55        {
56            get { return (ILookupParameter<DoubleValue>)Parameters[LowerTemperatureName]; }
57        }
58        public ILookupParameter<DoubleValue> StartTemperatureParameter
59        {
60            get { return (ILookupParameter<DoubleValue>)Parameters[StartTemperatureName]; }
61        }
62        public ILookupParameter<DoubleValue> EndTemperatureParameter
63        {
64            get { return (ILookupParameter<DoubleValue>)Parameters[EndTemperatureName]; }
65        }
66        public ILookupParameter<IntValue> TemperatureStartIndexParameter
67        {
68            get { return (ILookupParameter<IntValue>)Parameters[TemperatureStartIndexName]; }
69        }
70        public ILookupParameter<IntValue> IterationsParameter
71        {
72            get { return (ILookupParameter<IntValue>)Parameters[IterationsName]; }
73        }
74        public ILookupParameter<IOperator> AnnealingOperatorParameter
75        {
76            get { return (ILookupParameter<IOperator>)Parameters[AnnealingOperatorName]; }
77        }
78        public ILookupParameter<IntValue> MaximumIterationsParameter
79        {
80            get { return (ILookupParameter<IntValue>)Parameters[MaximumIterationsName]; }
81        }
82        private ValueParameter<IntValue> ThresholdParameter
83        {
84            get { return (ValueParameter<IntValue>)Parameters[ThresholdName]; }
85        }
86        private ValueParameter<IntValue> MaxNumberOfReheatsParameter
87        {
88            get { return (ValueParameter<IntValue>)Parameters[MaximumNumberOfReheatsName]; }
89        }
90        public ILookupParameter<BoolValue> IsAcceptedParameter
91        {
92            get { return (ILookupParameter<BoolValue>)Parameters[IsAcceptedName]; }
93        }
94        public ILookupParameter<ItemList<BoolValue>> AcceptanceMemoryParameter
95        {
96            get { return (ILookupParameter<ItemList<BoolValue>>)Parameters[AcceptanceMemoryName]; }
97        }
98        public ILookupParameter<IntValue> ReheatCountParameter
99        {
100            get { return (ILookupParameter<IntValue>)Parameters[ReheatCountName]; }
101        }
102        #endregion
103
104        public ConsecutiveRejectionTemperatureResetOperator() : base()
105        {
106            #region Create parameters
107            Parameters.Add(new LookupParameter<DoubleValue>(TemperatureName, "The current temperature."));
108            Parameters.Add(new LookupParameter<DoubleValue>(LowerTemperatureName, "The lower bound of the temperature."));
109            Parameters.Add(new LookupParameter<IntValue>(IterationsName, "The number of iterations."));
110            Parameters.Add(new LookupParameter<IOperator>(AnnealingOperatorName, "The operator that cools the temperature."));
111            Parameters.Add(new LookupParameter<IntValue>(TemperatureStartIndexName, "The index where the annealing or heating was last changed."));
112            Parameters.Add(new LookupParameter<DoubleValue>(StartTemperatureName, "The temperature from which cooling should occur."));
113            Parameters.Add(new LookupParameter<DoubleValue>(EndTemperatureName, "The temperature to which should be cooled."));
114            Parameters.Add(new LookupParameter<IntValue>(MaximumIterationsName, "The maximum number of iterations which should be processed."));
115            Parameters.Add(new LookupParameter<BoolValue>(IsAcceptedName, "Whether the move was accepted or not."));
116            Parameters.Add(new LookupParameter<ItemList<BoolValue>>(AcceptanceMemoryName, "Memorizes the last N acceptance decisions."));
117            Parameters.Add(new LookupParameter<IntValue>(ReheatCountName, "The number of reheats."));
118            Parameters.Add(new ValueParameter<IntValue>(ThresholdName, "How many consecutive rejected solutions must occur to trigger a reheat.", new IntValue(10)));
119            Parameters.Add(new ValueParameter<IntValue>(MaximumNumberOfReheatsName, "The maximum number of reheats which can be triggered", new IntValue(10)));
120            Parameters.Add(new ValueParameter<DoubleValue>(BaseResetTemperatureName, "The base reset temperature.", new DoubleValue(100d)));
121            Parameters.Add(new ValueParameter<DoubleValue>(MultiplyWithEachReheatName, "The amount the last reset temperature is multiplied with each reheat.", new DoubleValue(1d)));
122
123            #endregion
124
125            Parameterize();
126        }
127
128        [StorableConstructor]
129        protected ConsecutiveRejectionTemperatureResetOperator(bool deserializing) : base(deserializing) { }
130        protected ConsecutiveRejectionTemperatureResetOperator(ConsecutiveRejectionTemperatureResetOperator original, Cloner cloner) : base(original, cloner) { }
131
132
133        public override IDeepCloneable Clone(Cloner cloner)
134        {
135            return new ConsecutiveRejectionTemperatureResetOperator(this, cloner);
136        }
137
138        public void Parameterize()
139        {
140        }
141
142        public override IOperation Apply()
143        {
144            var acceptances = AcceptanceMemoryParameter.ActualValue;
145
146            acceptances.Add(IsAcceptedParameter.ActualValue);
147
148            if (acceptances.Count > ThresholdParameter.Value.Value) acceptances.RemoveAt(0);
149
150            var heating = acceptances.Count == ThresholdParameter.Value.Value && !acceptances.Any(x => x.Value) && !MaxNumberOfReheatsReached();
151
152            return heating ? Heat() : Cool();
153        }
154
155        private bool MaxNumberOfReheatsReached()
156        {
157            return ReheatCountParameter.ActualValue.Value >= MaxNumberOfReheatsParameter.Value.Value;
158        }
159
160        private IOperation Heat()
161        {
162            ReheatCountParameter.ActualValue.Value++;
163
164            AcceptanceMemoryParameter.ActualValue.Clear();
165
166            var temperature = Math.Max(BaseResetTemperatureParameter.Value.Value * Math.Pow(MultiplyWithEachReheatParameter.Value.Value, ReheatCountParameter.ActualValue.Value), TemperatureParameter.ActualValue.Value);
167
168            TemperatureParameter.ActualValue.Value = temperature;
169            TemperatureStartIndexParameter.ActualValue.Value = Math.Max(0, IterationsParameter.ActualValue.Value - 1);
170            StartTemperatureParameter.ActualValue.Value = TemperatureParameter.ActualValue.Value;
171            return base.Apply();
172        }
173
174        private IOperation Cool()
175        {
176            return new OperationCollection {
177                    ExecutionContext.CreateOperation(AnnealingOperatorParameter.ActualValue),
178                    base.Apply()
179                };
180        }
181    }
182}
Note: See TracBrowser for help on using the repository browser.