Free cookie consent management tool by TermsFeed Policy Generator

source: branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/AcceptanceRatioReheatingOperator.cs @ 14555

Last change on this file since 14555 was 14555, checked in by jschiess, 7 years ago

#1836 SA reheating strategies: Refactoring, Added Connolly Reheater Operator

File size: 10.6 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("AcceptanceRatioReheatingOperator", "Reheats the temperature if the acceptance is below a threshold.")]
19    [StorableClass]
20    public class AcceptanceRatioReheatingOperator : 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 UpperTemperatureName = "UpperTemperature";
33        private const string ReheatingOperatorName = "ReheatingOperator";
34        private const string ThresholdName = "Threshold";
35        private const string MemorySizeName = "MemorySize";
36        private const string CoolingName = "Cooling";
37        private const string IsAcceptedName = "IsAccepted";
38        private const string AcceptanceMemoryName = "AcceptanceMemory";
39
40
41        #endregion
42        #region Parameters
43        public ILookupParameter<DoubleValue> TemperatureParameter
44        {
45            get { return (ILookupParameter<DoubleValue>)Parameters[TemperatureName]; }
46        }
47        public ILookupParameter<DoubleValue> LowerTemperatureParameter
48        {
49            get { return (ILookupParameter<DoubleValue>)Parameters[LowerTemperatureName]; }
50        }
51        public ILookupParameter<DoubleValue> StartTemperatureParameter
52        {
53            get { return (ILookupParameter<DoubleValue>)Parameters[StartTemperatureName]; }
54        }
55        public ILookupParameter<DoubleValue> EndTemperatureParameter
56        {
57            get { return (ILookupParameter<DoubleValue>)Parameters[EndTemperatureName]; }
58        }
59        public ILookupParameter<IntValue> TemperatureStartIndexParameter
60        {
61            get { return (ILookupParameter<IntValue>)Parameters[TemperatureStartIndexName]; }
62        }
63        public ILookupParameter<IntValue> IterationsParameter
64        {
65            get { return (ILookupParameter<IntValue>)Parameters[IterationsName]; }
66        }
67        public ILookupParameter<IOperator> AnnealingOperatorParameter
68        {
69            get { return (ILookupParameter<IOperator>)Parameters[AnnealingOperatorName]; }
70        }
71        public ILookupParameter<IntValue> MaximumIterationsParameter
72        {
73            get { return (ILookupParameter<IntValue>)Parameters[MaximumIterationsName]; }
74        }
75        private ValueParameter<DoubleValue> UpperTemperatureParameter
76        {
77            get { return (ValueParameter<DoubleValue>)Parameters[UpperTemperatureName]; }
78        }
79        private IConstrainedValueParameter<IDiscreteDoubleValueModifier> ReheatingOperatorParameter
80        {
81            get { return (IConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters[ReheatingOperatorName]; }
82        }
83        private ValueParameter<DoubleRange> ThresholdParameter
84        {
85            get { return (ValueParameter<DoubleRange>)Parameters[ThresholdName]; }
86        }
87        private ValueParameter<IntValue> MemorySizeParameter
88        {
89            get { return (ValueParameter<IntValue>)Parameters[MemorySizeName]; }
90        }
91        public ILookupParameter<BoolValue> CoolingParameter
92        {
93            get { return (ILookupParameter<BoolValue>)Parameters[CoolingName]; }
94        }
95        public ILookupParameter<BoolValue> IsAcceptedParameter
96        {
97            get { return (ILookupParameter<BoolValue>)Parameters[IsAcceptedName]; }
98        }
99        public ILookupParameter<ItemList<BoolValue>> AcceptanceMemoryParameter
100        {
101            get { return (ILookupParameter<ItemList<BoolValue>>)Parameters[AcceptanceMemoryName]; }
102        }
103
104        #endregion
105
106        public AcceptanceRatioReheatingOperator() : base()
107        {
108            #region Create parameters
109            Parameters.Add(new LookupParameter<DoubleValue>(TemperatureName, "The current temperature."));
110            Parameters.Add(new LookupParameter<DoubleValue>(LowerTemperatureName, "The lower bound of the temperature."));
111            Parameters.Add(new LookupParameter<IntValue>(IterationsName, "The number of iterations."));
112            Parameters.Add(new LookupParameter<IOperator>(AnnealingOperatorName, "The operator that cools the temperature."));
113            Parameters.Add(new LookupParameter<IntValue>(TemperatureStartIndexName, "The index where the annealing or heating was last changed."));
114            Parameters.Add(new LookupParameter<DoubleValue>(StartTemperatureName, "The temperature from which cooling or reheating should occur."));
115            Parameters.Add(new LookupParameter<DoubleValue>(EndTemperatureName, "The temperature to which should be cooled or heated."));
116            Parameters.Add(new LookupParameter<IntValue>(MaximumIterationsName, "The maximum number of iterations which should be processed."));
117            Parameters.Add(new LookupParameter<BoolValue>(IsAcceptedName, "Whether the move was accepted or not."));
118            Parameters.Add(new LookupParameter<ItemList<BoolValue>>(AcceptanceMemoryName, "Memorizes the last N acceptance decisions."));
119            Parameters.Add(new LookupParameter<BoolValue>(CoolingName, "True when the temperature should be cooled, false otherwise."));
120            Parameters.Add(new ValueParameter<DoubleValue>(UpperTemperatureName, "The upper bound of the temperature.", new DoubleValue(100d)));
121            Parameters.Add(new ConstrainedValueParameter<IDiscreteDoubleValueModifier>(ReheatingOperatorName, "The operator that reheats the temperature."));
122            Parameters.Add(new ValueParameter<DoubleRange>(ThresholdName, "The threshold controls the temperature. If the average ratio of accepted moves goes below the start of the range the temperature is heated. If the the average ratio of accepted moves goes beyond the end of the range the temperature is cooled again.", new DoubleRange(0.2, 0.1)));
123            Parameters.Add(new ValueParameter<IntValue>(MemorySizeName, "The maximum size of the acceptance memory.", new IntValue(100)));
124
125            #endregion
126
127            foreach (var op in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name))
128            {
129                ReheatingOperatorParameter.ValidValues.Add((IDiscreteDoubleValueModifier) op);
130            }
131            Parameterize();
132        }
133
134        [StorableConstructor]
135        protected AcceptanceRatioReheatingOperator(bool deserializing) : base(deserializing) { }
136        protected AcceptanceRatioReheatingOperator(AcceptanceRatioReheatingOperator original, Cloner cloner) : base(original, cloner) { }
137
138
139        public override IDeepCloneable Clone(Cloner cloner)
140        {
141            return new AcceptanceRatioReheatingOperator(this, cloner);
142        }
143
144        public void Parameterize()
145        {
146            foreach (var op in ReheatingOperatorParameter.ValidValues)
147            {
148                op.IndexParameter.ActualName = IterationsName;
149                op.IndexParameter.Hidden = true;
150                op.StartIndexParameter.Value = null;
151                op.StartIndexParameter.ActualName = TemperatureStartIndexName;
152                op.EndIndexParameter.ActualName = MaximumIterationsParameter.Name;
153                op.ValueParameter.ActualName = TemperatureName;
154                op.ValueParameter.Hidden = true;
155                op.StartValueParameter.ActualName = StartTemperatureName;
156                op.StartValueParameter.Hidden = true;
157                op.EndValueParameter.ActualName = UpperTemperatureName;
158                op.EndValueParameter.Value = UpperTemperatureParameter.Value;
159                op.EndValueParameter.Hidden = true;
160            }
161        }
162
163        public override IOperation Apply()
164        {
165
166            var acceptances = AcceptanceMemoryParameter.ActualValue;
167            var cooling = CoolingParameter.ActualValue.Value;
168
169            acceptances.Add(IsAcceptedParameter.ActualValue);
170
171            if (acceptances.Count > MemorySizeParameter.Value.Value) acceptances.RemoveAt(0);
172
173            var ratioStart = ThresholdParameter.Value.Start;
174            var ratioEnd = ThresholdParameter.Value.End;
175            var ratio = acceptances.Average(x => x.Value ? 1.0 : 0.0);
176
177           
178            if (!cooling && ratio >= ratioEnd)
179            {
180                // if we are heating, but should be cooling
181                cooling = true;
182                TemperatureStartIndexParameter.ActualValue.Value = Math.Max(0, IterationsParameter.ActualValue.Value - 1);
183                StartTemperatureParameter.ActualValue.Value = TemperatureParameter.ActualValue.Value;
184                EndTemperatureParameter.ActualValue.Value = LowerTemperatureParameter.ActualValue.Value;
185            }
186            else if (cooling && ratio <= ratioStart)
187            {
188                // if we are cooling but should be heating
189                cooling = false;
190                TemperatureStartIndexParameter.ActualValue.Value = Math.Max(0, IterationsParameter.ActualValue.Value - 1);
191                StartTemperatureParameter.ActualValue.Value = TemperatureParameter.ActualValue.Value;
192                EndTemperatureParameter.ActualValue.Value = UpperTemperatureParameter.Value.Value;
193            }
194
195            CoolingParameter.ActualValue.Value = cooling;
196
197            return cooling ? Cool() : Heat();
198        }
199
200        private IOperation Heat()
201        {
202            return new OperationCollection {
203                    ExecutionContext.CreateOperation(ReheatingOperatorParameter.Value),
204                    base.Apply()
205                };
206        }
207
208        private IOperation Cool()
209        {
210            return new OperationCollection {
211                    ExecutionContext.CreateOperation(AnnealingOperatorParameter.ActualValue),
212                    base.Apply()
213                };
214        }
215    }
216}
Note: See TracBrowser for help on using the repository browser.