source: branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/TemperatureController.cs @ 15001

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

#1836 SA reheating strategies: Newest version of reheating

File size: 12.7 KB
Line 
1#region License Information
2
3/* HeuristicLab
4 * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
5 *
6 * This file is part of HeuristicLab.
7 *
8 * HeuristicLab is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * HeuristicLab is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#endregion
23
24using System;
25using System.Linq;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Operators;
30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32using HeuristicLab.Optimization;
33
34namespace HeuristicLab.Algorithms.SimulatedAnnealing
35{
36    [Item("TemperatureController", "Decides based on information from the heatingoperator, whether to use cooling or heating and calls the appropriate operator.")]
37    [StorableClass]
38    public class TemperatureController : SingleSuccessorOperator
39    {
40        #region Strings
41        private const string ReheatingOperatorName = "ReheatingOperator";
42        private const string AnnealingOperatorName = "AnnealingOperator";
43        private const string MaximumIterationsName = "MaximumIterations";
44        private const string InitialTemperatureName = "InitialTemperature";
45        private const string LowerTemperatureName = "LowerTemperature";
46        private const string IterationsName = "Iterations";
47        private const string TemperatureStartIndexName = "TemperatureStartIndex";
48        private const string CoolingName = "Cooling";
49        private const string StartTemperatureName = "StartTemperature";
50        private const string EndTemperatureName = "EndTemperature";
51        private const string TemperatureName = "Temperature";
52        private const string IsAcceptedName = "IsAccepted";
53        private const string ConsecutiveRejectedSolutionsCountName = "ConsecutiveRejectedSolutions";
54        private const string AverageAcceptanceRatioName = "AverageAcceptanceRatio";
55        private const string AcceptanceMemoryName = "AcceptanceMemory";
56        private const string LastQualityName = "LastQuality";
57        private const string UphillMovesMemoryName = "UphillMovesMemory";
58        private const string MaximizationName = "Maximization";
59        private const string MoveQualityName = "MoveQuality";
60        private const string InitialAcceptanceRateName = "InitialAcceptanceRate";
61        private const string ResultsName = "Results";
62        private const string CalculatedInitialTemperatureName = "CalculatedInitialTemperature";
63
64        #endregion
65
66        #region Parameter Properties
67        public ILookupParameter<DoubleValue> TemperatureParameter
68        {
69            get { return (ILookupParameter<DoubleValue>)Parameters[TemperatureName]; }
70        }
71        public ILookupParameter<DoubleValue> InitialTemperatureParameter
72        {
73            get { return (ILookupParameter<DoubleValue>)Parameters[InitialTemperatureName]; }
74        }
75        public IValueLookupParameter<DoubleValue> LowerTemperatureParameter
76        {
77            get { return (IValueLookupParameter<DoubleValue>)Parameters[LowerTemperatureName]; }
78        }
79        public ILookupParameter<DoubleValue> StartTemperatureParameter
80        {
81            get { return (ILookupParameter<DoubleValue>)Parameters[StartTemperatureName]; }
82        }
83        public ILookupParameter<DoubleValue> EndTemperatureParameter
84        {
85            get { return (ILookupParameter<DoubleValue>)Parameters[EndTemperatureName]; }
86        }
87        public ILookupParameter<IntValue> TemperatureStartIndexParameter
88        {
89            get { return (ILookupParameter<IntValue>)Parameters[TemperatureStartIndexName]; }
90        }
91        public ILookupParameter<BoolValue> CoolingParameter
92        {
93            get { return (ILookupParameter<BoolValue>)Parameters[CoolingName]; }
94        }
95        public ILookupParameter<IntValue> IterationsParameter
96        {
97            get { return (ILookupParameter<IntValue>)Parameters[IterationsName]; }
98        }
99        public IValueLookupParameter<IntValue> MaximumIterationsParameter
100        {
101            get { return (IValueLookupParameter<IntValue>)Parameters[MaximumIterationsName]; }
102        }
103        public IValueLookupParameter<IOperator> AnnealingOperatorParameter
104        {
105            get { return (IValueLookupParameter<IOperator>)Parameters[AnnealingOperatorName]; }
106        }
107        public IValueLookupParameter<IReheatingOperator> ReheatingOperatorParameter
108        {
109            get { return (IValueLookupParameter<IReheatingOperator>)Parameters[ReheatingOperatorName]; }
110        }
111        public ILookupParameter<BoolValue> IsAcceptedParameter
112        {
113            get { return (ILookupParameter<BoolValue>)Parameters[IsAcceptedName]; }
114        }
115        public ILookupParameter<ItemList<BoolValue>> AcceptanceMemoryParameter
116        {
117            get { return (ILookupParameter<ItemList<BoolValue>>)Parameters[AcceptanceMemoryName]; }
118        }
119        public ILookupParameter<ItemList<DoubleValue>> UphillMovesMemoryParameter
120        {
121            get { return (ILookupParameter<ItemList<DoubleValue>>)Parameters[UphillMovesMemoryName]; }
122        }
123        public ILookupParameter<DoubleValue> MoveQualityParameter
124        {
125            get { return (ILookupParameter<DoubleValue>)Parameters[MoveQualityName]; }
126        }
127        public ILookupParameter<DoubleValue> LastQualityParameter
128        {
129            get { return (ILookupParameter<DoubleValue>)Parameters[LastQualityName]; }
130        }
131        public IValueLookupParameter<BoolValue> MaximizationParameter
132        {
133            get { return (IValueLookupParameter<BoolValue>)Parameters[MaximizationName]; }
134        }
135        public ILookupParameter<DoubleValue> InitialAcceptanceRateParameter
136        {
137            get { return (ILookupParameter<DoubleValue>)Parameters[InitialAcceptanceRateName]; }
138        }
139        public ILookupParameter<IntValue> ConsecutiveRejectedSolutionsCountParameter
140        {
141            get { return (ILookupParameter<IntValue>)Parameters[ConsecutiveRejectedSolutionsCountName]; }
142        }
143        public ILookupParameter<DoubleValue> AverageAcceptanceRatioParameter
144        {
145            get { return (ILookupParameter<DoubleValue>)Parameters[AverageAcceptanceRatioName]; }
146        }
147        #endregion
148
149        [StorableConstructor]
150        protected TemperatureController(bool deserializing) : base(deserializing) { }
151        protected TemperatureController(TemperatureController original, Cloner cloner) : base(original, cloner) { }
152        public TemperatureController()
153          : base()
154        {
155            Parameters.Add(new LookupParameter<DoubleValue>(TemperatureName, "The current temperature."));
156            Parameters.Add(new ValueLookupParameter<DoubleValue>(LowerTemperatureName, "The lower bound of the temperature."));
157            Parameters.Add(new LookupParameter<IntValue>(IterationsName, "The number of iterations."));
158            Parameters.Add(new ValueLookupParameter<IntValue>(MaximumIterationsName, "The maximum number of iterations which should be processed."));
159            Parameters.Add(new ValueLookupParameter<BoolValue>(MaximizationName, "True if the problem is a maximization problem, otherwise false."));
160            Parameters.Add(new ValueLookupParameter<IOperator>(AnnealingOperatorName, "The operator that cools the temperature."));
161            Parameters.Add(new ValueLookupParameter<IReheatingOperator>(ReheatingOperatorName, "The operator that reheats the temperature if necessary."));
162            Parameters.Add(new LookupParameter<IntValue>(TemperatureStartIndexName, "The index where the annealing or heating was last changed."));
163            Parameters.Add(new LookupParameter<BoolValue>(CoolingName, "True when the temperature should be cooled, false otherwise."));
164            Parameters.Add(new LookupParameter<DoubleValue>(StartTemperatureName, "The temperature from which cooling or reheating should occur."));
165            Parameters.Add(new LookupParameter<DoubleValue>(EndTemperatureName, "The temperature to which should be cooled or heated."));
166            Parameters.Add(new LookupParameter<BoolValue>(IsAcceptedName, "Whether the move was accepted or not."));
167            Parameters.Add(new LookupParameter<ItemList<BoolValue>>(AcceptanceMemoryName, "Memorizes the last N acceptance decisions."));
168            Parameters.Add(new LookupParameter<DoubleValue>(InitialTemperatureName, "The initial temperature."));
169
170            Parameters.Add(new LookupParameter<ItemList<DoubleValue>>(UphillMovesMemoryName, "Memorizes the last 100 uphill moves."));
171            Parameters.Add(new LookupParameter<DoubleValue>(MoveQualityName, "The value which represents the quality of a move."));
172            Parameters.Add(new LookupParameter<DoubleValue>(LastQualityName, "The value which represents the quality of the last move."));
173            Parameters.Add(new LookupParameter<DoubleValue>(InitialAcceptanceRateName, "The initial acceptance rate of average-sized hills used to calculate the initial temperature."));
174            Parameters.Add(new LookupParameter<IntValue>(ConsecutiveRejectedSolutionsCountName, "Amount of consecutive rejected solutions."));
175            Parameters.Add(new LookupParameter<DoubleValue>(AverageAcceptanceRatioName, "Average acceptance over full acceptance memory."));
176
177        }
178
179        public override IDeepCloneable Clone(Cloner cloner)
180        {
181            return new TemperatureController(this, cloner);
182        }
183
184        public override IOperation Apply()
185        {
186            var uphillMoves = UphillMovesMemoryParameter.ActualValue;
187            if (!InitialTemperatureFound())
188            {
189                return findInitialTemperature();
190            }else
191            {
192                return new OperationCollection {
193                    ExecutionContext.CreateOperation(ReheatingOperatorParameter.ActualValue),
194                    base.Apply()
195                };
196            }
197        }
198
199        private IOperation findInitialTemperature()
200        {
201            var currentQuality = MoveQualityParameter.ActualValue.Value;
202            var lastQuality = LastQualityParameter.ActualValue.Value;
203            var isMaximation = MaximizationParameter.ActualValue.Value;
204            var hillMemory = UphillMovesMemoryParameter.ActualValue;
205           
206            if(lastQuality != -1)
207            {
208                double hillSize = CalculateHillSize(lastQuality, currentQuality, isMaximation);
209               
210                if(hillSize > 0)
211                {
212                    hillMemory.Add(new DoubleValue(hillSize));
213                    if(InitialTemperatureFound())
214                    {
215                        var results = (ResultCollection)ExecutionContext.Parent.Scope.Variables[ResultsName].Value;
216                        var initialTemperature = CalculateInitialTemperatureBasedOnAverageHillSize(hillMemory);
217                        InitialTemperatureParameter.ActualValue.Value = initialTemperature;
218                        TemperatureParameter.ActualValue.Value = initialTemperature;
219                        TemperatureStartIndexParameter.ActualValue.Value = Math.Max(0, IterationsParameter.ActualValue.Value - 1);
220                        StartTemperatureParameter.ActualValue.Value = TemperatureParameter.ActualValue.Value;
221                        results.Add(new Result(CalculatedInitialTemperatureName, new DoubleValue(initialTemperature)));
222                    }
223                }
224            }
225
226            LastQualityParameter.ActualValue.Value = currentQuality;
227            return base.Apply();
228        }
229
230        private double CalculateInitialTemperatureBasedOnAverageHillSize(ItemList<DoubleValue> hillMemory)
231        {
232            var averageHillSize = hillMemory.Average(x => x.Value);
233            return -(averageHillSize / Math.Log(InitialAcceptanceRateParameter.ActualValue.Value));
234
235        }
236
237        private double CalculateHillSize(double lastQuality, double currentQuality, bool isMaximation)
238        {
239            return isMaximation ? lastQuality - currentQuality : currentQuality - lastQuality;
240        }
241
242        private bool InitialTemperatureFound()
243        {
244            return UphillMovesMemoryParameter.ActualValue.Count == 100;
245        }
246    }
247}
Note: See TracBrowser for help on using the repository browser.