Free cookie consent management tool by TermsFeed Policy Generator

source: branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/SimulatedAnnealing - postopt.cs @ 9437

Last change on this file since 9437 was 9437, checked in by abeham, 11 years ago

#1836: pulled SA 3.4 from trunk

File size: 33.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using HeuristicLab.Analysis;
23using HeuristicLab.Common;
24using HeuristicLab.Core;
25using HeuristicLab.Data;
26using HeuristicLab.Operators;
27using HeuristicLab.Optimization;
28using HeuristicLab.Optimization.Operators;
29using HeuristicLab.Parameters;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31using HeuristicLab.PluginInfrastructure;
32using HeuristicLab.Random;
33using System;
34using System.Linq;
35
36namespace HeuristicLab.Algorithms.SimulatedAnnealing {
37  [Item("Simulated Annealing", "An advanced simulated annealing algorithm.")]
38  [Creatable("Algorithms")]
39  [StorableClass]
40  public sealed class SimulatedAnnealing : HeuristicOptimizationEngineAlgorithm, IStorableContent {
41    #region Strings
42    private const string SeedName = "Seed";
43    private const string SetSeedRandomlyName = "SetSeedRandomly";
44    private const string MoveGeneratorName = "MoveGenerator";
45    private const string MoveEvaluatorName = "MoveEvaluator";
46    private const string MoveMakerName = "MoveMaker";
47    private const string AnnealingOperatorName = "AnnealingOperator";
48    private const string HeatingOperatorName = "HeatingOperator";
49    private const string MaximumIterationsName = "MaximumIterations";
50    private const string UpperTemperatureName = "UpperTemperature";
51    private const string LowerTemperatureName = "LowerTemperature";
52    private const string AnalyzerName = "Analyzer";
53    private const string RandomName = "Random";
54    private const string EvaluatedMovesName = "EvaluatedMoves";
55    private const string IterationsName = "Iterations";
56    private const string TemperatureStartIndexName = "TemperatureStartIndex";
57    private const string CoolingName = "Cooling";
58    private const string StartTemperatureName = "StartTemperature";
59    private const string EndTemperatureName = "EndTemperature";
60    private const string TemperatureName = "Temperature";
61    private const string ResultsName = "Results";
62    private const string TemperatureChartName = "Temperature Chart";
63    private const string TemperatureAnalyzerName = "Temperature Analyzer";
64    private const string ThresholdName = "Threshold";
65    private const string MemorySizeName = "MemorySize";
66    private const string PostOptimizationIterationsName = "PostOptimizationIterations";
67    private const string PostOptimizationTemperatureName = "PostOptimizationTemperature";
68    #endregion
69
70    public string Filename { get; set; }
71
72    #region Problem Properties
73    public override Type ProblemType {
74      get { return typeof(ISingleObjectiveHeuristicOptimizationProblem); }
75    }
76    public new ISingleObjectiveHeuristicOptimizationProblem Problem {
77      get { return (ISingleObjectiveHeuristicOptimizationProblem)base.Problem; }
78      set { base.Problem = value; }
79    }
80    #endregion
81
82    #region Parameter Properties
83    private ValueParameter<IntValue> SeedParameter {
84      get { return (ValueParameter<IntValue>)Parameters[SeedName]; }
85    }
86    private ValueParameter<BoolValue> SetSeedRandomlyParameter {
87      get { return (ValueParameter<BoolValue>)Parameters[SetSeedRandomlyName]; }
88    }
89    public IConstrainedValueParameter<IMultiMoveGenerator> MoveGeneratorParameter {
90      get { return (IConstrainedValueParameter<IMultiMoveGenerator>)Parameters[MoveGeneratorName]; }
91    }
92    public IConstrainedValueParameter<IMoveMaker> MoveMakerParameter {
93      get { return (IConstrainedValueParameter<IMoveMaker>)Parameters[MoveMakerName]; }
94    }
95    public IConstrainedValueParameter<ISingleObjectiveMoveEvaluator> MoveEvaluatorParameter {
96      get { return (IConstrainedValueParameter<ISingleObjectiveMoveEvaluator>)Parameters[MoveEvaluatorName]; }
97    }
98    public IConstrainedValueParameter<IDiscreteDoubleValueModifier> AnnealingOperatorParameter {
99      get { return (IConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters[AnnealingOperatorName]; }
100    }
101    public OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier> HeatingOperatorParameter {
102      get { return (OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters[HeatingOperatorName]; }
103    }
104    private ValueParameter<DoubleRange> ThresholdParameter {
105      get { return (ValueParameter<DoubleRange>)Parameters[ThresholdName]; }
106    }
107    private ValueParameter<IntValue> MemorySizeParameter {
108      get { return (ValueParameter<IntValue>)Parameters[MemorySizeName]; }
109    }
110    private ValueParameter<IntValue> MaximumIterationsParameter {
111      get { return (ValueParameter<IntValue>)Parameters[MaximumIterationsName]; }
112    }
113    private ValueParameter<DoubleValue> UpperTemperatureParameter {
114      get { return (ValueParameter<DoubleValue>)Parameters[UpperTemperatureName]; }
115    }
116    private ValueParameter<DoubleValue> LowerTemperatureParameter {
117      get { return (ValueParameter<DoubleValue>)Parameters[LowerTemperatureName]; }
118    }
119    private ValueParameter<MultiAnalyzer> AnalyzerParameter {
120      get { return (ValueParameter<MultiAnalyzer>)Parameters[AnalyzerName]; }
121    }
122    private IValueParameter<IntValue> PostOptimizationIterationsParameter {
123      get { return (IValueParameter<IntValue>)Parameters[PostOptimizationIterationsName]; }
124    }
125    private IValueParameter<DoubleValue> PostOptimizationTemperatureParameter {
126      get { return (IValueParameter<DoubleValue>)Parameters[PostOptimizationTemperatureName]; }
127    }
128    #endregion
129
130    #region Properties
131    public IntValue Seed {
132      get { return SeedParameter.Value; }
133      set { SeedParameter.Value = value; }
134    }
135    public BoolValue SetSeedRandomly {
136      get { return SetSeedRandomlyParameter.Value; }
137      set { SetSeedRandomlyParameter.Value = value; }
138    }
139    public IMultiMoveGenerator MoveGenerator {
140      get { return MoveGeneratorParameter.Value; }
141      set { MoveGeneratorParameter.Value = value; }
142    }
143    public IMoveMaker MoveMaker {
144      get { return MoveMakerParameter.Value; }
145      set { MoveMakerParameter.Value = value; }
146    }
147    public ISingleObjectiveMoveEvaluator MoveEvaluator {
148      get { return MoveEvaluatorParameter.Value; }
149      set { MoveEvaluatorParameter.Value = value; }
150    }
151    public IDiscreteDoubleValueModifier AnnealingOperator {
152      get { return AnnealingOperatorParameter.Value; }
153      set { AnnealingOperatorParameter.Value = value; }
154    }
155    public IDiscreteDoubleValueModifier HeatingOperator {
156      get { return HeatingOperatorParameter.Value; }
157      set { HeatingOperatorParameter.Value = value; }
158    }
159    public IntValue MaximumIterations {
160      get { return MaximumIterationsParameter.Value; }
161      set { MaximumIterationsParameter.Value = value; }
162    }
163    public DoubleValue UpperTemperature {
164      get { return UpperTemperatureParameter.Value; }
165      set { UpperTemperatureParameter.Value = value; }
166    }
167    public DoubleValue LowerTemperature {
168      get { return LowerTemperatureParameter.Value; }
169      set { LowerTemperatureParameter.Value = value; }
170    }
171    public MultiAnalyzer Analyzer {
172      get { return AnalyzerParameter.Value; }
173      set { AnalyzerParameter.Value = value; }
174    }
175    public DoubleRange Threshold {
176      get { return ThresholdParameter.Value; }
177      set { ThresholdParameter.Value = value; }
178    }
179    public IntValue MemorySize {
180      get { return MemorySizeParameter.Value; }
181      set { MemorySizeParameter.Value = value; }
182    }
183    public IntValue PostOptimizationIterations {
184      get { return PostOptimizationIterationsParameter.Value; }
185      set { PostOptimizationIterationsParameter.Value = value; }
186    }
187    private RandomCreator RandomCreator {
188      get { return (RandomCreator)OperatorGraph.InitialOperator; }
189    }
190    private SolutionsCreator SolutionsCreator {
191      get { return (SolutionsCreator)RandomCreator.Successor; }
192    }
193    private SimulatedAnnealingMainLoop MainLoop {
194      get { return OperatorGraph.Iterate().OfType<SimulatedAnnealingMainLoop>().First(); }
195    }
196    #endregion
197
198    [StorableConstructor]
199    private SimulatedAnnealing(bool deserializing) : base(deserializing) { }
200    private SimulatedAnnealing(SimulatedAnnealing original, Cloner cloner)
201      : base(original, cloner) {
202      RegisterEventHandlers();
203    }
204    public SimulatedAnnealing()
205      : base() {
206      Parameters.Add(new ValueParameter<IntValue>(SeedName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
207      Parameters.Add(new ValueParameter<BoolValue>(SetSeedRandomlyName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
208      Parameters.Add(new ConstrainedValueParameter<IMultiMoveGenerator>(MoveGeneratorName, "The operator used to generate moves to the neighborhood of the current solution."));
209      Parameters.Add(new ConstrainedValueParameter<ISingleObjectiveMoveEvaluator>(MoveEvaluatorName, "The operator used to evaluate a move."));
210      Parameters.Add(new ConstrainedValueParameter<IMoveMaker>(MoveMakerName, "The operator used to perform a move."));
211      Parameters.Add(new ConstrainedValueParameter<IDiscreteDoubleValueModifier>(AnnealingOperatorName, "The operator used to cool the temperature."));
212      Parameters.Add(new OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>(HeatingOperatorName, "The operator used to heat the temperature."));
213      Parameters.Add(new ValueParameter<IntValue>(MaximumIterationsName, "The maximum number of generations which should be processed.", new IntValue(10000)));
214      Parameters.Add(new ValueParameter<DoubleValue>(UpperTemperatureName, "The upper bound for the temperature.", new DoubleValue(100)));
215      Parameters.Add(new ValueParameter<DoubleValue>(LowerTemperatureName, "The lower bound for the temperature.", new DoubleValue(1e-5)));
216      Parameters.Add(new ValueParameter<MultiAnalyzer>(AnalyzerName, "The operator used to analyze each iteration.", new MultiAnalyzer()));
217      Parameters.Add(new ValueParameter<IntValue>(MemorySizeName, "The maximum size of the acceptance memory.", new IntValue(200)));
218      Parameters.Add(new ValueParameter<DoubleRange>(ThresholdName, "The threshold controls the temperature in case a heating operator is specified. 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.02, 0.1)));
219      Parameters.Add(new ValueParameter<IntValue>(PostOptimizationIterationsName, "Number of iterations after MaximumIterations that the search continues with a certain temperature.", new IntValue(0)));
220      Parameters.Add(new ValueParameter<DoubleValue>(PostOptimizationTemperatureName, "The temperature that should be used for the post optimization phase, use 0 for local search.", new DoubleValue(0)));
221      PostOptimizationIterationsParameter.Hidden = true;
222      PostOptimizationTemperatureParameter.Hidden = true;
223
224      var randomCreator = new RandomCreator();
225      var solutionsCreator = new SolutionsCreator();
226      var variableCreator = new VariableCreator();
227      var startTemperatureAssigner = new Assigner();
228      var endTemperatureAssigner = new Assigner();
229      var temperatureAssigner = new Assigner();
230      var resultsCollector = new ResultsCollector();
231      var mainLoop = new SimulatedAnnealingMainLoop();
232      var temperatureAssigner2 = new Assigner();
233      var maxIterationAssigner2 = new Assigner();
234      var postOptCounter = new IntCounter();
235      var postOptComparator = new Comparator();
236      var postOptBranch = new ConditionalBranch();
237      var postOptIterationsCounter = new IntCounter();
238      var postOptMainProcessor = new SubScopesProcessor();
239      var postOptMoveGenerator = new Placeholder();
240      var postOptMoveEvaluationProcessor = new SubScopesProcessor();
241      var postOptMoveEvaluator = new Placeholder();
242      var postOptEvaluatedMovesCounter = new IntCounter();
243      var postOptQualityComparator = new ProbabilisticQualityComparator();
244      var postOptAcceptsQualityBranch = new ConditionalBranch();
245      var postOptMoveMaker = new Placeholder();
246      var postOptSubScopesRemover = new SubScopesRemover();
247      var analyzer = new Placeholder();
248
249      OperatorGraph.InitialOperator = randomCreator;
250
251      randomCreator.RandomParameter.ActualName = RandomName;
252      randomCreator.SeedParameter.ActualName = SeedParameter.Name;
253      randomCreator.SeedParameter.Value = null;
254      randomCreator.SetSeedRandomlyParameter.ActualName = SetSeedRandomlyParameter.Name;
255      randomCreator.SetSeedRandomlyParameter.Value = null;
256      randomCreator.Successor = solutionsCreator;
257
258      solutionsCreator.NumberOfSolutions = new IntValue(1);
259      solutionsCreator.Successor = variableCreator;
260
261      variableCreator.Name = "Initialize Variables";
262      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>(EvaluatedMovesName, new IntValue(0)));
263      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>(IterationsName, new IntValue(0)));
264      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>(TemperatureStartIndexName, new IntValue(0)));
265      variableCreator.CollectedValues.Add(new ValueParameter<BoolValue>(CoolingName, new BoolValue(true)));
266      variableCreator.Successor = startTemperatureAssigner;
267
268      startTemperatureAssigner.Name = "Assign Start Temperature";
269      startTemperatureAssigner.LeftSideParameter.ActualName = StartTemperatureName;
270      startTemperatureAssigner.RightSideParameter.ActualName = UpperTemperatureParameter.Name;
271      startTemperatureAssigner.Successor = endTemperatureAssigner;
272
273      endTemperatureAssigner.Name = "Assign End Temperature";
274      endTemperatureAssigner.LeftSideParameter.ActualName = EndTemperatureName;
275      endTemperatureAssigner.RightSideParameter.ActualName = LowerTemperatureParameter.Name;
276      endTemperatureAssigner.Successor = temperatureAssigner;
277
278      temperatureAssigner.Name = "Initialize Temperature";
279      temperatureAssigner.LeftSideParameter.ActualName = TemperatureName;
280      temperatureAssigner.RightSideParameter.ActualName = StartTemperatureName;
281      temperatureAssigner.Successor = resultsCollector;
282
283      resultsCollector.CopyValue = new BoolValue(false);
284      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>(EvaluatedMovesName, null));
285      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>(IterationsName, null));
286      resultsCollector.ResultsParameter.ActualName = ResultsName;
287      resultsCollector.Successor = mainLoop;
288
289      mainLoop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
290      mainLoop.AnnealingOperatorParameter.ActualName = AnnealingOperatorParameter.Name;
291      mainLoop.MemorySizeParameter.ActualName = MemorySizeParameter.Name;
292      mainLoop.ThresholdParameter.ActualName = ThresholdParameter.Name;
293      mainLoop.CoolingParameter.ActualName = CoolingName;
294      mainLoop.EndTemperatureParameter.ActualName = EndTemperatureName;
295      mainLoop.EvaluatedMovesParameter.ActualName = EvaluatedMovesName;
296      mainLoop.HeatingOperatorParameter.ActualName = HeatingOperatorParameter.Name;
297      mainLoop.IterationsParameter.ActualName = IterationsName;
298      mainLoop.LowerTemperatureParameter.ActualName = LowerTemperatureParameter.Name;
299      mainLoop.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
300      mainLoop.MoveEvaluatorParameter.ActualName = MoveEvaluatorParameter.Name;
301      mainLoop.MoveGeneratorParameter.ActualName = MoveGeneratorParameter.Name;
302      mainLoop.MoveMakerParameter.ActualName = MoveMakerParameter.Name;
303      mainLoop.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
304      mainLoop.ResultsParameter.ActualName = ResultsName;
305      mainLoop.StartTemperatureParameter.ActualName = StartTemperatureName;
306      mainLoop.TemperatureStartIndexParameter.ActualName = TemperatureStartIndexName;
307      mainLoop.TemperatureParameter.ActualName = TemperatureName;
308      mainLoop.UpperTemperatureParameter.ActualName = UpperTemperatureParameter.Name;
309      mainLoop.Successor = temperatureAssigner2;
310
311      temperatureAssigner2.Name = "Temperature := 0";
312      temperatureAssigner2.LeftSideParameter.ActualName = TemperatureName;
313      temperatureAssigner2.RightSideParameter.ActualName = PostOptimizationTemperatureParameter.Name;
314      temperatureAssigner2.Successor = maxIterationAssigner2;
315
316      maxIterationAssigner2.Name = "Prepare post-optimization phase";
317      maxIterationAssigner2.LeftSideParameter.ActualName = "TempMaxIter";
318      maxIterationAssigner2.RightSideParameter.ActualName = MaximumIterationsParameter.Name;
319      maxIterationAssigner2.Successor = postOptCounter;
320
321      postOptCounter.Name = "MaximumIterations += PostOptimizationIterations";
322      postOptCounter.Increment = null;
323      postOptCounter.IncrementParameter.ActualName = PostOptimizationIterationsParameter.Name;
324      postOptCounter.ValueParameter.ActualName = "TempMaxIter";
325      postOptCounter.Successor = postOptComparator;
326
327      postOptComparator.Name = "Iterations >= MaximumIterations";
328      postOptComparator.Comparison = new Comparison(ComparisonType.GreaterOrEqual);
329      postOptComparator.LeftSideParameter.ActualName = IterationsName;
330      postOptComparator.ResultParameter.ActualName = "Terminate";
331      postOptComparator.RightSideParameter.ActualName = "TempMaxIter";
332      postOptComparator.Successor = postOptBranch;
333
334      postOptBranch.Name = "Terminate?";
335      postOptBranch.ConditionParameter.ActualName = "Terminate";
336      postOptBranch.FalseBranch = postOptIterationsCounter;
337      postOptBranch.TrueBranch = null;
338
339      postOptIterationsCounter.Name = "Iterations++";
340      postOptIterationsCounter.Increment = new IntValue(1);
341      postOptIterationsCounter.ValueParameter.ActualName = IterationsName;
342      postOptIterationsCounter.Successor = postOptMainProcessor;
343
344      postOptMainProcessor.Parallel = new BoolValue(false);
345      postOptMainProcessor.Operators.Add(postOptMoveGenerator);
346      postOptMainProcessor.Successor = postOptComparator;
347
348      postOptMoveGenerator.Name = "MoveGenerator";
349      postOptMoveGenerator.OperatorParameter.ActualName = MoveGeneratorParameter.Name;
350      postOptMoveGenerator.Successor = postOptMoveEvaluationProcessor;
351
352      postOptMoveEvaluationProcessor.Operators.Add(postOptMoveEvaluator);
353      postOptMoveEvaluationProcessor.Successor = postOptSubScopesRemover;
354
355      postOptMoveEvaluator.Name = "MoveEvaluator";
356      postOptMoveEvaluator.OperatorParameter.ActualName = MoveEvaluatorParameter.Name;
357      postOptMoveEvaluator.Successor = postOptEvaluatedMovesCounter;
358
359      postOptEvaluatedMovesCounter.Name = "EvaluatedMoves++";
360      postOptEvaluatedMovesCounter.Increment = new IntValue(1);
361      postOptEvaluatedMovesCounter.ValueParameter.ActualName = EvaluatedMovesName;
362      postOptEvaluatedMovesCounter.Successor = postOptQualityComparator;
363
364      postOptQualityComparator.Name = "Is Solution Acceptable?";
365      postOptQualityComparator.ResultParameter.ActualName = "IsAccepted";
366      postOptQualityComparator.DampeningParameter.ActualName = TemperatureName;
367      postOptQualityComparator.Successor = postOptAcceptsQualityBranch;
368
369      postOptAcceptsQualityBranch.ConditionParameter.ActualName = "IsAccepted";
370      postOptAcceptsQualityBranch.TrueBranch = postOptMoveMaker;
371      postOptAcceptsQualityBranch.Successor = null;
372      postOptAcceptsQualityBranch.FalseBranch = null;
373
374      postOptMoveMaker.Name = "MoveMaker";
375      postOptMoveMaker.OperatorParameter.ActualName = MoveMakerParameter.Name;
376      postOptMoveMaker.Successor = null;
377
378      postOptSubScopesRemover.RemoveAllSubScopes = true;
379      postOptSubScopesRemover.Successor = analyzer;
380
381      analyzer.Name = "Analyzer";
382      analyzer.OperatorParameter.ActualName = AnalyzerParameter.Name;
383      analyzer.Successor = null;
384
385      foreach (var op in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name)) {
386        AnnealingOperatorParameter.ValidValues.Add(op);
387        HeatingOperatorParameter.ValidValues.Add((IDiscreteDoubleValueModifier)op.Clone());
388      }
389
390      UpdateAnalyzers();
391
392      Parameterize();
393
394      RegisterEventHandlers();
395    }
396
397    public override IDeepCloneable Clone(Cloner cloner) {
398      return new SimulatedAnnealing(this, cloner);
399    }
400
401    [StorableHook(HookType.AfterDeserialization)]
402    private void AfterDeserialization() {
403      RegisterEventHandlers();
404    }
405
406    private void RegisterEventHandlers() {
407      if (Problem != null) {
408        Problem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
409        foreach (var op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
410          op.MoveQualityParameter.ActualNameChanged += MoveEvaluator_MoveQualityParameter_ActualNameChanged;
411        }
412      }
413      MoveGeneratorParameter.ValueChanged += MoveGeneratorParameter_ValueChanged;
414      MoveEvaluatorParameter.ValueChanged += MoveEvaluatorParameter_ValueChanged;
415    }
416
417    public override void Prepare() {
418      if (Problem != null && MoveGenerator != null && MoveMaker != null && MoveEvaluator != null)
419        base.Prepare();
420    }
421
422    #region Events
423    protected override void OnProblemChanged() {
424      foreach (var op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
425        op.MoveQualityParameter.ActualNameChanged += MoveEvaluator_MoveQualityParameter_ActualNameChanged;
426      }
427      UpdateMoveGenerator();
428      UpdateMoveOperators();
429      UpdateAnalyzers();
430      Parameterize();
431      Problem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
432      base.OnProblemChanged();
433    }
434    protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
435      Parameterize();
436      base.Problem_SolutionCreatorChanged(sender, e);
437    }
438    protected override void Problem_EvaluatorChanged(object sender, EventArgs e) {
439      Parameterize();
440      Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
441      base.Problem_EvaluatorChanged(sender, e);
442    }
443    protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
444      foreach (var op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
445        op.MoveQualityParameter.ActualNameChanged -= MoveEvaluator_MoveQualityParameter_ActualNameChanged;
446        op.MoveQualityParameter.ActualNameChanged += MoveEvaluator_MoveQualityParameter_ActualNameChanged;
447      }
448      UpdateMoveGenerator();
449      UpdateMoveOperators();
450      UpdateAnalyzers();
451      Parameterize();
452      base.Problem_OperatorsChanged(sender, e);
453    }
454    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
455      Parameterize();
456    }
457    private void MoveGeneratorParameter_ValueChanged(object sender, EventArgs e) {
458      UpdateMoveOperators();
459    }
460    private void MoveEvaluatorParameter_ValueChanged(object sender, EventArgs e) {
461      Parameterize();
462    }
463    private void MoveEvaluator_MoveQualityParameter_ActualNameChanged(object sender, EventArgs e) {
464      if (sender == MoveEvaluator) Parameterize();
465    }
466    #endregion
467
468    #region Helpers
469
470    private void UpdateMoveGenerator() {
471      var oldMoveGenerator = MoveGenerator;
472      var defaultMoveGenerator = Problem.Operators.OfType<IMultiMoveGenerator>().FirstOrDefault();
473
474      MoveGeneratorParameter.ValidValues.Clear();
475
476      if (Problem != null) {
477        foreach (var generator in Problem.Operators.OfType<IMultiMoveGenerator>().OrderBy(x => x.Name))
478          MoveGeneratorParameter.ValidValues.Add(generator);
479      }
480
481      if (oldMoveGenerator != null) {
482        var newMoveGenerator = MoveGeneratorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveGenerator.GetType());
483        if (newMoveGenerator != null) MoveGenerator = newMoveGenerator;
484        else oldMoveGenerator = null;
485      }
486      if (oldMoveGenerator == null && defaultMoveGenerator != null)
487        MoveGenerator = defaultMoveGenerator;
488
489      UpdateMoveOperators();
490    }
491
492    private void UpdateMoveOperators() {
493      var oldMoveMaker = MoveMaker;
494      var oldMoveEvaluator = MoveEvaluator;
495
496      MoveMakerParameter.ValidValues.Clear();
497      MoveEvaluatorParameter.ValidValues.Clear();
498
499      if (MoveGenerator != null) {
500        var moveTypes = MoveGenerator.GetType().GetInterfaces().Where(x => typeof(IMoveOperator).IsAssignableFrom(x)).ToList();
501        foreach (var type in moveTypes.ToList()) {
502          if (moveTypes.Any(t => t != type && type.IsAssignableFrom(t)))
503            moveTypes.Remove(type);
504        }
505        var operators = Problem.Operators.Where(op => moveTypes.Any(m => m.IsInstanceOfType(op))).ToList();
506        var defaultMoveMaker = operators.OfType<IMoveMaker>().FirstOrDefault();
507        var defaultMoveEvaluator = operators.OfType<ISingleObjectiveMoveEvaluator>().FirstOrDefault();
508
509        foreach (var moveMaker in operators.OfType<IMoveMaker>().OrderBy(op => op.Name))
510          MoveMakerParameter.ValidValues.Add(moveMaker);
511
512        foreach (var moveEvaluator in operators.OfType<ISingleObjectiveMoveEvaluator>().OrderBy(op => op.Name))
513          MoveEvaluatorParameter.ValidValues.Add(moveEvaluator);
514
515        if (oldMoveMaker != null) {
516          var mm = MoveMakerParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
517          if (mm != null) MoveMaker = mm;
518          else oldMoveMaker = null;
519        }
520        if (oldMoveMaker == null && defaultMoveMaker != null)
521          MoveMaker = defaultMoveMaker;
522
523        if (oldMoveEvaluator != null) {
524          var me = MoveEvaluatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
525          if (me != null) MoveEvaluator = me;
526          else oldMoveEvaluator = null;
527        }
528        if (oldMoveEvaluator == null & defaultMoveEvaluator != null)
529          MoveEvaluator = defaultMoveEvaluator;
530      }
531    }
532
533    private void UpdateAnalyzers() {
534      Analyzer.Operators.Clear();
535      if (Problem != null) {
536        foreach (var analyzer in Problem.Operators.OfType<IAnalyzer>()) {
537          foreach (var param in analyzer.Parameters.OfType<IScopeTreeLookupParameter>())
538            param.Depth = 0;
539          Analyzer.Operators.Add(analyzer, analyzer.EnabledByDefault);
540        }
541      }
542      var qualityAnalyzer = new QualityAnalyzer();
543      var temperatureAnalyzer = new SingleValueAnalyzer { Name = TemperatureAnalyzerName };
544      Analyzer.Operators.Add(qualityAnalyzer, qualityAnalyzer.EnabledByDefault);
545      Analyzer.Operators.Add(temperatureAnalyzer, temperatureAnalyzer.EnabledByDefault);
546    }
547
548    private void Parameterize() {
549
550      #region IStochasticOperator
551      if (Problem != null) {
552        foreach (var op in Problem.Operators.OfType<IStochasticOperator>()) {
553          op.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
554          op.RandomParameter.Hidden = true;
555        }
556      }
557      #endregion
558
559      #region IIterationBasedOperator
560      if (Problem != null) {
561        foreach (var op in Problem.Operators.OfType<IIterationBasedOperator>()) {
562          op.IterationsParameter.ActualName = IterationsName;
563          op.IterationsParameter.Hidden = true;
564          op.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
565          op.MaximumIterationsParameter.Hidden = true;
566        }
567      }
568      #endregion
569
570      #region Analyzers
571
572      foreach (var qualityAnalyzer in Analyzer.Operators.OfType<QualityAnalyzer>()) {
573        qualityAnalyzer.ResultsParameter.ActualName = ResultsName;
574        if (Problem != null) {
575          qualityAnalyzer.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
576          qualityAnalyzer.MaximizationParameter.Hidden = true;
577          qualityAnalyzer.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
578          qualityAnalyzer.QualityParameter.Depth = 0;
579          qualityAnalyzer.QualityParameter.Hidden = true;
580          qualityAnalyzer.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
581          qualityAnalyzer.BestKnownQualityParameter.Hidden = true;
582        } else {
583          qualityAnalyzer.MaximizationParameter.Hidden = false;
584          qualityAnalyzer.QualityParameter.Hidden = false;
585          qualityAnalyzer.BestKnownQualityParameter.Hidden = false;
586        }
587      }
588
589      var temperatureAnalyzer = Analyzer.Operators.OfType<SingleValueAnalyzer>().FirstOrDefault(x => x.Name == TemperatureAnalyzerName);
590      if (temperatureAnalyzer != null) {
591        temperatureAnalyzer.ResultsParameter.ActualName = ResultsName;
592        temperatureAnalyzer.ResultsParameter.Hidden = true;
593        temperatureAnalyzer.ValueParameter.ActualName = TemperatureName;
594        temperatureAnalyzer.ValueParameter.Hidden = true;
595        temperatureAnalyzer.ValuesParameter.ActualName = TemperatureChartName;
596        temperatureAnalyzer.ValuesParameter.Hidden = true;
597      }
598
599      #endregion
600
601      #region SolutionCreator
602      if (Problem != null) {
603        SolutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
604        SolutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
605      }
606      #endregion
607
608      #region Annealing/Reheating Operators
609      foreach (var op in AnnealingOperatorParameter.ValidValues) {
610        op.IndexParameter.ActualName = IterationsName;
611        op.IndexParameter.Hidden = true;
612        op.StartIndexParameter.Value = null;
613        op.StartIndexParameter.ActualName = TemperatureStartIndexName;
614        op.EndIndexParameter.ActualName = MaximumIterationsParameter.Name;
615        op.ValueParameter.ActualName = TemperatureName;
616        op.ValueParameter.Hidden = true;
617        op.StartValueParameter.ActualName = StartTemperatureName;
618        op.StartValueParameter.Hidden = true;
619        op.EndValueParameter.ActualName = LowerTemperatureParameter.Name;
620        op.EndValueParameter.Hidden = true;
621      }
622      foreach (var op in HeatingOperatorParameter.ValidValues) {
623        op.IndexParameter.ActualName = IterationsName;
624        op.IndexParameter.Hidden = true;
625        op.StartIndexParameter.Value = null;
626        op.StartIndexParameter.ActualName = TemperatureStartIndexName;
627        op.EndIndexParameter.ActualName = MaximumIterationsParameter.Name;
628        op.ValueParameter.ActualName = TemperatureName;
629        op.ValueParameter.Hidden = true;
630        op.StartValueParameter.ActualName = StartTemperatureName;
631        op.StartValueParameter.Hidden = true;
632        op.EndValueParameter.ActualName = UpperTemperatureParameter.Name;
633        op.EndValueParameter.Hidden = true;
634      }
635      #endregion
636
637      #region Move Operators
638      if (Problem != null) {
639        foreach (var op in Problem.Operators.OfType<IMultiMoveGenerator>()) {
640          op.SampleSizeParameter.Value = new IntValue(1);
641          op.SampleSizeParameter.Hidden = true;
642        }
643        foreach (var op in Problem.Operators.OfType<IMoveMaker>()) {
644          op.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
645          op.QualityParameter.Hidden = true;
646          if (MoveEvaluator != null) {
647            op.MoveQualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
648            op.MoveQualityParameter.Hidden = true;
649          } else {
650            op.MoveQualityParameter.Hidden = false;
651          }
652        }
653        foreach (var op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
654          op.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
655          op.QualityParameter.Hidden = true;
656        }
657      }
658      #endregion
659
660      #region MainLoop
661      if (Problem != null) {
662        MainLoop.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
663        MainLoop.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
664        MainLoop.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
665        if (MoveEvaluator != null)
666          MainLoop.MoveQualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
667      }
668      #endregion
669
670      #region PostOptimization
671      if (Problem != null) {
672        var op = OperatorGraph.Iterate().OfType<ProbabilisticQualityComparator>().FirstOrDefault(x => x.Name == "Is Solution Acceptable?");
673        if (op == null) throw new InvalidOperationException("PostOptimizationQualityComparer not found!");
674        if (MoveEvaluator != null)
675          op.LeftSideParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
676        op.RightSideParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
677      }
678      #endregion
679    }
680    #endregion
681  }
682}
Note: See TracBrowser for help on using the repository browser.