1 | using HeuristicLab.Operators;
|
---|
2 | using System;
|
---|
3 | using System.Collections.Generic;
|
---|
4 | using System.Linq;
|
---|
5 | using System.Text;
|
---|
6 | using System.Threading.Tasks;
|
---|
7 | using HeuristicLab.Common;
|
---|
8 | using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
|
---|
9 | using HeuristicLab.Core;
|
---|
10 | using HeuristicLab.Data;
|
---|
11 | using HeuristicLab.Parameters;
|
---|
12 | using HeuristicLab.Optimization;
|
---|
13 | using HeuristicLab.PluginInfrastructure;
|
---|
14 |
|
---|
15 | namespace HeuristicLab.Algorithms.SimulatedAnnealing
|
---|
16 | {
|
---|
17 | [Item("Continuous Reheater", "Reheats the temperature continuously, while the acceptance rate of solutions is under the threshold.")]
|
---|
18 | [StorableClass]
|
---|
19 | public class ContinuousReheater : SingleSuccessorOperator, ISimulatedAnnealingHeatingStrategy
|
---|
20 | {
|
---|
21 | #region Strings
|
---|
22 | private const string UpperTemperatureName = "UpperTemperature";
|
---|
23 | private const string ReheatingOperatorName = "ReheatingOperator";
|
---|
24 | private const string ThresholdName = "Threshold";
|
---|
25 | private const string MemorySizeName = "MemorySize";
|
---|
26 |
|
---|
27 |
|
---|
28 | private const string IterationsName = "Iterations";
|
---|
29 | private const string MaximumIterationsName = "MaximumIterations";
|
---|
30 | private const string TemperatureStartIndexName = "TemperatureStartIndex";
|
---|
31 | private const string StartTemperatureName = "StartTemperature";
|
---|
32 | private const string EndTemperatureName = "EndTemperature";
|
---|
33 | private const string TemperatureName = "Temperature";
|
---|
34 | private const string CoolingName = "Cooling";
|
---|
35 | private const string IsAcceptedName = "IsAccepted";
|
---|
36 | private const string AcceptanceMemoryName = "AcceptanceMemory";
|
---|
37 |
|
---|
38 |
|
---|
39 | #endregion
|
---|
40 | #region Parameters
|
---|
41 | private ValueParameter<DoubleValue> UpperTemperatureParameter
|
---|
42 | {
|
---|
43 | get { return (ValueParameter<DoubleValue>)Parameters[UpperTemperatureName]; }
|
---|
44 | }
|
---|
45 | private IConstrainedValueParameter<IDiscreteDoubleValueModifier> ReheatingOperatorParameter
|
---|
46 | {
|
---|
47 | get { return (IConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters[ReheatingOperatorName]; }
|
---|
48 | }
|
---|
49 | private ValueParameter<DoubleRange> ThresholdParameter
|
---|
50 | {
|
---|
51 | get { return (ValueParameter<DoubleRange>)Parameters[ThresholdName]; }
|
---|
52 | }
|
---|
53 | private ValueParameter<IntValue> MemorySizeParameter
|
---|
54 | {
|
---|
55 | get { return (ValueParameter<IntValue>)Parameters[MemorySizeName]; }
|
---|
56 | }
|
---|
57 |
|
---|
58 | public ILookupParameter<IntValue> IterationsParameter
|
---|
59 | {
|
---|
60 | get { return (ILookupParameter<IntValue>)Parameters[IterationsName]; }
|
---|
61 | }
|
---|
62 | public IValueLookupParameter<IntValue> MaximumIterationsParameter
|
---|
63 | {
|
---|
64 | get { return (IValueLookupParameter<IntValue>)Parameters[MaximumIterationsName]; }
|
---|
65 | }
|
---|
66 | public ILookupParameter<DoubleValue> TemperatureParameter
|
---|
67 | {
|
---|
68 | get { return (ILookupParameter<DoubleValue>)Parameters[TemperatureName]; }
|
---|
69 | }
|
---|
70 | public ILookupParameter<DoubleValue> EndTemperatureParameter
|
---|
71 | {
|
---|
72 | get { return (ILookupParameter<DoubleValue>)Parameters[EndTemperatureName]; }
|
---|
73 | }
|
---|
74 | public ILookupParameter<DoubleValue> StartTemperatureParameter
|
---|
75 | {
|
---|
76 | get { return (ILookupParameter<DoubleValue>)Parameters[StartTemperatureName]; }
|
---|
77 | }
|
---|
78 | public ILookupParameter<IntValue> TemperatureStartIndexParameter
|
---|
79 | {
|
---|
80 | get { return (ILookupParameter<IntValue>)Parameters[TemperatureStartIndexName]; }
|
---|
81 | }
|
---|
82 | public ILookupParameter<BoolValue> CoolingParameter
|
---|
83 | {
|
---|
84 | get { return (ILookupParameter<BoolValue>)Parameters[CoolingName]; }
|
---|
85 | }
|
---|
86 | public ILookupParameter<BoolValue> IsAcceptedParameter
|
---|
87 | {
|
---|
88 | get { return (ILookupParameter<BoolValue>)Parameters[IsAcceptedName]; }
|
---|
89 | }
|
---|
90 | public ILookupParameter<ItemList<BoolValue>> AcceptanceMemoryParameter
|
---|
91 | {
|
---|
92 | get { return (ILookupParameter<ItemList<BoolValue>>)Parameters[AcceptanceMemoryName]; }
|
---|
93 | }
|
---|
94 |
|
---|
95 | #endregion
|
---|
96 | #region Properties
|
---|
97 | public DoubleValue UpperTemperature
|
---|
98 | {
|
---|
99 | get { return UpperTemperatureParameter.Value; }
|
---|
100 | set { UpperTemperatureParameter.Value = value; }
|
---|
101 | }
|
---|
102 | public IDiscreteDoubleValueModifier ReheatingOperator
|
---|
103 | {
|
---|
104 | get { return ReheatingOperatorParameter.Value; }
|
---|
105 | set { ReheatingOperatorParameter.Value = value; }
|
---|
106 | }
|
---|
107 | public DoubleRange AcceptanceThreshold
|
---|
108 | {
|
---|
109 | get { return ThresholdParameter.Value; }
|
---|
110 | set { ThresholdParameter.Value = value; }
|
---|
111 | }
|
---|
112 | public IntValue AcceptanceMemorySize
|
---|
113 | {
|
---|
114 | get { return MemorySizeParameter.Value; }
|
---|
115 | set { MemorySizeParameter.Value = value; }
|
---|
116 | }
|
---|
117 | #endregion
|
---|
118 |
|
---|
119 | public ContinuousReheater() : base()
|
---|
120 | {
|
---|
121 | #region Create parameters
|
---|
122 | Parameters.Add(new ValueParameter<DoubleValue>(UpperTemperatureName, "The upper bound of the temperature.", new DoubleValue(100d)));
|
---|
123 | Parameters.Add(new ConstrainedValueParameter<IDiscreteDoubleValueModifier>(ReheatingOperatorName, "Reheating operator."));
|
---|
124 | 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.1, 0.05)));
|
---|
125 | Parameters.Add(new ValueParameter<IntValue>(MemorySizeName, "The maximum size of the acceptance memory.", new IntValue(100)));
|
---|
126 |
|
---|
127 | Parameters.Add(new LookupParameter<IntValue>(IterationsName, "The number of iterations."));
|
---|
128 | Parameters.Add(new LookupParameter<DoubleValue>(TemperatureName, "The current temperature."));
|
---|
129 | Parameters.Add(new ValueLookupParameter<IntValue>(MaximumIterationsName, "The maximum number of iterations which should be processed."));
|
---|
130 | Parameters.Add(new LookupParameter<IntValue>(TemperatureStartIndexName, "The index where the annealing or heating was last changed."));
|
---|
131 | Parameters.Add(new LookupParameter<BoolValue>(CoolingName, "True when the temperature should be cooled, false otherwise."));
|
---|
132 | Parameters.Add(new LookupParameter<DoubleValue>(StartTemperatureName, "The temperature from which cooling or reheating should occur."));
|
---|
133 | Parameters.Add(new LookupParameter<DoubleValue>(EndTemperatureName, "The temperature to which should be cooled or heated."));
|
---|
134 | Parameters.Add(new LookupParameter<BoolValue>(IsAcceptedName, "Whether the move was accepted or not."));
|
---|
135 | Parameters.Add(new LookupParameter<ItemList<BoolValue>>(AcceptanceMemoryName, "Memorizes the last N acceptance decisions."));
|
---|
136 | #endregion
|
---|
137 |
|
---|
138 | foreach (var op in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name))
|
---|
139 | {
|
---|
140 | ReheatingOperatorParameter.ValidValues.Add(op);
|
---|
141 | }
|
---|
142 |
|
---|
143 | Parameterize();
|
---|
144 | }
|
---|
145 |
|
---|
146 | [StorableConstructor]
|
---|
147 | protected ContinuousReheater(bool deserializing) : base(deserializing) { }
|
---|
148 | protected ContinuousReheater(ContinuousReheater original, Cloner cloner) : base(original, cloner) { }
|
---|
149 |
|
---|
150 |
|
---|
151 | public override IDeepCloneable Clone(Cloner cloner)
|
---|
152 | {
|
---|
153 | return new ContinuousReheater(this, cloner);
|
---|
154 | }
|
---|
155 |
|
---|
156 | public void Parameterize()
|
---|
157 | {
|
---|
158 | foreach (var op in ReheatingOperatorParameter.ValidValues)
|
---|
159 | {
|
---|
160 | op.IndexParameter.ActualName = IterationsName;
|
---|
161 | op.IndexParameter.Hidden = true;
|
---|
162 | op.StartIndexParameter.Value = null;
|
---|
163 | op.StartIndexParameter.ActualName = TemperatureStartIndexName;
|
---|
164 | op.EndIndexParameter.ActualName = MaximumIterationsParameter.Name;
|
---|
165 | op.ValueParameter.ActualName = TemperatureName;
|
---|
166 | op.ValueParameter.Hidden = true;
|
---|
167 | op.StartValueParameter.ActualName = StartTemperatureName;
|
---|
168 | op.StartValueParameter.Hidden = true;
|
---|
169 | op.EndValueParameter.ActualName = EndTemperatureName;
|
---|
170 | op.EndValueParameter.Hidden = true;
|
---|
171 | }
|
---|
172 | }
|
---|
173 |
|
---|
174 | public bool ShouldReheat(bool cooling, ItemList<BoolValue> acceptances) {
|
---|
175 |
|
---|
176 | if (acceptances.Count > MemorySizeParameter.Value.Value) acceptances.RemoveAt(0);
|
---|
177 |
|
---|
178 | var ratioStart = ThresholdParameter.Value.Start;
|
---|
179 | var ratioEnd = ThresholdParameter.Value.End;
|
---|
180 | var ratio = acceptances.Average(x => x.Value ? 1.0 : 0.0);
|
---|
181 | if (!cooling && ratio >= ratioEnd)
|
---|
182 | {
|
---|
183 | return false;
|
---|
184 | }
|
---|
185 | else if (cooling && ratio <= ratioStart)
|
---|
186 | { // temperature is cooled, but should be heated
|
---|
187 | return true;
|
---|
188 | }
|
---|
189 | return !cooling;
|
---|
190 | }
|
---|
191 | public override IOperation Apply()
|
---|
192 | {
|
---|
193 | var iterations = IterationsParameter.ActualValue.Value;
|
---|
194 | TemperatureStartIndexParameter.ActualValue.Value = Math.Max(0, iterations - 1);
|
---|
195 | StartTemperatureParameter.ActualValue.Value = TemperatureParameter.ActualValue.Value;
|
---|
196 | EndTemperatureParameter.ActualValue.Value = UpperTemperatureParameter.Value.Value;
|
---|
197 |
|
---|
198 | return new OperationCollection {
|
---|
199 | ExecutionContext.CreateOperation(ReheatingOperatorParameter.Value), base.Apply()};
|
---|
200 | }
|
---|
201 | }
|
---|
202 | }
|
---|