Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.Algorithms.RandomSearch/3.3/RandomSearchAlgorithm.cs @ 17334

Last change on this file since 17334 was 17181, checked in by swagner, 5 years ago

#2875: Merged r17180 from trunk to stable

File size: 17.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 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 System;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Analysis;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Operators;
30using HeuristicLab.Optimization;
31using HeuristicLab.Optimization.Operators;
32using HeuristicLab.Parameters;
33using HEAL.Attic;
34using HeuristicLab.Random;
35
36namespace HeuristicLab.Algorithms.RandomSearch {
37  [Item("Random Search Algorithm (RS)", "A random search algorithm.")]
38  [Creatable(CreatableAttribute.Categories.SingleSolutionAlgorithms, Priority = 150)]
39  [StorableType("51EFBCCE-00A7-4E97-8177-85774E71E681")]
40  public sealed class RandomSearchAlgorithm : HeuristicOptimizationEngineAlgorithm, IStorableContent {
41    public string Filename { get; set; }
42
43    #region Problem Properties
44    public override Type ProblemType {
45      get { return typeof(IHeuristicOptimizationProblem); }
46    }
47    private ISingleObjectiveHeuristicOptimizationProblem SingleObjectiveProblem {
48      get { return Problem as ISingleObjectiveHeuristicOptimizationProblem; }
49    }
50    private IMultiObjectiveHeuristicOptimizationProblem MultiObjectiveProblem {
51      get { return Problem as IMultiObjectiveHeuristicOptimizationProblem; }
52    }
53    #endregion
54
55    #region Parameter Properties
56    private IFixedValueParameter<IntValue> SeedParameter {
57      get { return (IFixedValueParameter<IntValue>)Parameters["Seed"]; }
58    }
59    private IFixedValueParameter<BoolValue> SetSeedRandomlyParameter {
60      get { return (IFixedValueParameter<BoolValue>)Parameters["SetSeedRandomly"]; }
61    }
62    private IFixedValueParameter<MultiAnalyzer> AnalyzerParameter {
63      get { return (IFixedValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
64    }
65    private IFixedValueParameter<IntValue> MaximumEvaluatedSolutionsParameter {
66      get { return (IFixedValueParameter<IntValue>)Parameters["MaximumEvaluatedSolutions"]; }
67    }
68    private IFixedValueParameter<IntValue> BatchSizeParameter {
69      get { return (IFixedValueParameter<IntValue>)Parameters["BatchSize"]; }
70    }
71    private IFixedValueParameter<IntValue> MaximumIterationsParameter {
72      get { return (IFixedValueParameter<IntValue>)Parameters["MaximumIterations"]; }
73    }
74    private IFixedValueParameter<MultiTerminator> TerminatorParameter {
75      get { return (IFixedValueParameter<MultiTerminator>)Parameters["Terminator"]; }
76    }
77    #endregion
78
79    #region Properties
80    public int Seed {
81      get { return SeedParameter.Value.Value; }
82      set { SeedParameter.Value.Value = value; }
83    }
84    public bool SetSeedRandomly {
85      get { return SetSeedRandomlyParameter.Value.Value; }
86      set { SetSeedRandomlyParameter.Value.Value = value; }
87    }
88    public MultiAnalyzer Analyzer {
89      get { return AnalyzerParameter.Value; }
90    }
91    public int MaximumEvaluatedSolutions {
92      get { return MaximumEvaluatedSolutionsParameter.Value.Value; }
93      set { MaximumEvaluatedSolutionsParameter.Value.Value = value; }
94    }
95    public int BatchSize {
96      get { return BatchSizeParameter.Value.Value; }
97      set { BatchSizeParameter.Value.Value = value; }
98    }
99    public int MaximumIterations {
100      get { return MaximumIterationsParameter.Value.Value; }
101      set { MaximumIterationsParameter.Value.Value = value; }
102    }
103    public MultiTerminator Terminators {
104      get { return TerminatorParameter.Value; }
105    }
106    #endregion
107
108    #region Helper Properties
109    private SolutionsCreator SolutionsCreator {
110      get { return OperatorGraph.Iterate().OfType<SolutionsCreator>().First(); }
111    }
112    #endregion
113
114    #region Preconfigured Analyzers
115    [Storable]
116    private BestAverageWorstQualityAnalyzer singleObjectiveQualityAnalyzer;
117    #endregion
118
119    #region Preconfigured Terminators
120    [Storable]
121    private ComparisonTerminator<IntValue> evaluationsTerminator;
122    [Storable]
123    private ExecutionTimeTerminator executionTimeTerminator;
124    [Storable]
125    private SingleObjectiveQualityTerminator qualityTerminator;
126    #endregion
127
128    #region Constructors
129    [StorableConstructor]
130    private RandomSearchAlgorithm(StorableConstructorFlag _) : base(_) { }
131    [StorableHook(HookType.AfterDeserialization)]
132    private void AfterDeserialization() {
133      Initialize();
134    }
135    private RandomSearchAlgorithm(RandomSearchAlgorithm original, Cloner cloner)
136      : base(original, cloner) {
137      singleObjectiveQualityAnalyzer = cloner.Clone(original.singleObjectiveQualityAnalyzer);
138      evaluationsTerminator = cloner.Clone(original.evaluationsTerminator);
139      qualityTerminator = cloner.Clone(original.qualityTerminator);
140      executionTimeTerminator = cloner.Clone(original.executionTimeTerminator);
141      Initialize();
142    }
143    public override IDeepCloneable Clone(Cloner cloner) {
144      return new RandomSearchAlgorithm(this, cloner);
145    }
146
147    public RandomSearchAlgorithm()
148      : base() {
149      #region Add parameters
150      Parameters.Add(new FixedValueParameter<IntValue>("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
151      Parameters.Add(new FixedValueParameter<BoolValue>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
152      Parameters.Add(new FixedValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze the solutions each iteration.", new MultiAnalyzer()));
153      Parameters.Add(new FixedValueParameter<IntValue>("MaximumEvaluatedSolutions", "The number of random solutions the algorithm should evaluate.", new IntValue(1000)));
154      Parameters.Add(new FixedValueParameter<IntValue>("BatchSize", "The number of random solutions that are evaluated (in parallel) per iteration.", new IntValue(100)));
155      Parameters.Add(new FixedValueParameter<IntValue>("MaximumIterations", "The number of iterations that the algorithm will run.", new IntValue(10)) { Hidden = true });
156      Parameters.Add(new FixedValueParameter<MultiTerminator>("Terminator", "The termination criteria that defines if the algorithm should continue or stop.", new MultiTerminator()) { Hidden = true });
157      #endregion
158
159      #region Create operators
160      var randomCreator = new RandomCreator();
161      var variableCreator = new VariableCreator() { Name = "Initialize Variables" };
162      var resultsCollector = new ResultsCollector();
163      var solutionCreator = new SolutionsCreator() { Name = "Create Solutions" };
164      var analyzerPlaceholder = new Placeholder() { Name = "Analyzer (Placeholder)" };
165      var evaluationsCounter = new IntCounter() { Name = "Increment EvaluatedSolutions" };
166      var subScopesRemover = new SubScopesRemover();
167      var iterationsCounter = new IntCounter() { Name = "Increment Iterations" };
168      var terminationOperator = new TerminationOperator();
169      #endregion
170
171      #region Create and parameterize operator graph
172      OperatorGraph.InitialOperator = randomCreator;
173
174      randomCreator.SeedParameter.Value = null;
175      randomCreator.SeedParameter.ActualName = SeedParameter.Name;
176      randomCreator.SetSeedRandomlyParameter.Value = null;
177      randomCreator.SetSeedRandomlyParameter.ActualName = SetSeedRandomlyParameter.Name;
178      randomCreator.Successor = variableCreator;
179
180      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("Iterations", new IntValue(0)));
181      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("EvaluatedSolutions", new IntValue(0)));
182      variableCreator.Successor = resultsCollector;
183
184      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Iterations", "The current iteration number."));
185      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The current number of evaluated solutions."));
186      resultsCollector.Successor = solutionCreator;
187
188      solutionCreator.NumberOfSolutionsParameter.ActualName = BatchSizeParameter.Name;
189      solutionCreator.ParallelParameter.Value.Value = true;
190      solutionCreator.Successor = evaluationsCounter;
191
192      evaluationsCounter.ValueParameter.ActualName = "EvaluatedSolutions";
193      evaluationsCounter.Increment = null;
194      evaluationsCounter.IncrementParameter.ActualName = BatchSizeParameter.Name;
195      evaluationsCounter.Successor = analyzerPlaceholder;
196
197      analyzerPlaceholder.OperatorParameter.ActualName = AnalyzerParameter.Name;
198      analyzerPlaceholder.Successor = subScopesRemover;
199
200      subScopesRemover.RemoveAllSubScopes = true;
201      subScopesRemover.Successor = iterationsCounter;
202
203      iterationsCounter.ValueParameter.ActualName = "Iterations";
204      iterationsCounter.Increment = new IntValue(1);
205      iterationsCounter.Successor = terminationOperator;
206
207      terminationOperator.TerminatorParameter.ActualName = TerminatorParameter.Name;
208      terminationOperator.ContinueBranch = solutionCreator;
209      #endregion
210
211      #region Create analyzers
212      singleObjectiveQualityAnalyzer = new BestAverageWorstQualityAnalyzer();
213      #endregion
214
215      #region Create terminators
216      evaluationsTerminator = new ComparisonTerminator<IntValue>("EvaluatedSolutions", ComparisonType.Less, MaximumEvaluatedSolutionsParameter) { Name = "Evaluated solutions." };
217      qualityTerminator = new SingleObjectiveQualityTerminator() { Name = "Quality" };
218      executionTimeTerminator = new ExecutionTimeTerminator(this, new TimeSpanValue(TimeSpan.FromMinutes(5)));
219      #endregion
220
221      #region Parameterize
222      UpdateAnalyzers();
223      ParameterizeAnalyzers();
224      UpdateTerminators();
225      #endregion
226
227      Initialize();
228    }
229    #endregion
230
231    #region Events
232    public override void Prepare() {
233      if (Problem != null)
234        base.Prepare();
235    }
236    protected override void OnProblemChanged() {
237      base.OnProblemChanged();
238      ParameterizeStochasticOperator(Problem.SolutionCreator);
239      foreach (var @operator in Problem.Operators.OfType<IOperator>())
240        ParameterizeStochasticOperator(@operator);
241
242      ParameterizeIterationBasedOperators();
243
244      ParameterizeSolutionsCreator();
245      ParameterizeAnalyzers();
246      ParameterizeTerminators();
247
248      if (SingleObjectiveProblem != null)
249        SingleObjectiveProblem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
250
251      UpdateAnalyzers();
252      UpdateTerminators();
253    }
254
255    protected override void RegisterProblemEvents() {
256      base.RegisterProblemEvents();
257      if (SingleObjectiveProblem != null) {
258        var maximizationParameter = (IValueParameter<BoolValue>)SingleObjectiveProblem.MaximizationParameter;
259        if (maximizationParameter != null) maximizationParameter.ValueChanged += new EventHandler(MaximizationParameter_ValueChanged);
260      }
261    }
262    protected override void DeregisterProblemEvents() {
263      if (SingleObjectiveProblem != null) {
264        var maximizationParameter = (IValueParameter<BoolValue>)SingleObjectiveProblem.MaximizationParameter;
265        if (maximizationParameter != null) maximizationParameter.ValueChanged -= new EventHandler(MaximizationParameter_ValueChanged);
266      }
267      base.DeregisterProblemEvents();
268    }
269
270    protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
271      base.Problem_SolutionCreatorChanged(sender, e);
272      ParameterizeStochasticOperator(Problem.SolutionCreator);
273
274      if (SingleObjectiveProblem != null)
275        SingleObjectiveProblem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
276
277      ParameterizeSolutionsCreator();
278      ParameterizeAnalyzers();
279    }
280    protected override void Problem_EvaluatorChanged(object sender, EventArgs e) {
281      base.Problem_EvaluatorChanged(sender, e);
282      foreach (var @operator in Problem.Operators.OfType<IOperator>())
283        ParameterizeStochasticOperator(@operator);
284
285      UpdateAnalyzers();
286
287      ParameterizeSolutionsCreator();
288    }
289    protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
290      base.Problem_OperatorsChanged(sender, e);
291      ParameterizeIterationBasedOperators();
292      UpdateTerminators();
293    }
294    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
295      ParameterizeAnalyzers();
296    }
297    private void MaximizationParameter_ValueChanged(object sender, EventArgs e) {
298      ParameterizeTerminators();
299    }
300    private void QualityAnalyzer_CurrentBestQualityParameter_NameChanged(object sender, EventArgs e) {
301      ParameterizeTerminators();
302    }
303
304    #endregion
305
306    #region Parameterization
307    private void Initialize() {
308      if (SingleObjectiveProblem != null)
309        SingleObjectiveProblem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
310
311      singleObjectiveQualityAnalyzer.CurrentBestQualityParameter.NameChanged += QualityAnalyzer_CurrentBestQualityParameter_NameChanged;
312
313      MaximumEvaluatedSolutionsParameter.Value.ValueChanged += MaximumEvaluatedSolutions_ValueChanged;
314      BatchSizeParameter.Value.ValueChanged += BatchSize_ValueChanged;
315    }
316    private void ParameterizeSolutionsCreator() {
317      SolutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
318      SolutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
319    }
320    private void ParameterizeAnalyzers() {
321      singleObjectiveQualityAnalyzer.ResultsParameter.ActualName = "Results";
322      singleObjectiveQualityAnalyzer.ResultsParameter.Hidden = true;
323      singleObjectiveQualityAnalyzer.QualityParameter.Depth = 1;
324
325      if (SingleObjectiveProblem != null) {
326        singleObjectiveQualityAnalyzer.MaximizationParameter.ActualName = SingleObjectiveProblem.MaximizationParameter.Name;
327        singleObjectiveQualityAnalyzer.MaximizationParameter.Hidden = true;
328        singleObjectiveQualityAnalyzer.QualityParameter.ActualName = SingleObjectiveProblem.Evaluator.QualityParameter.ActualName;
329        singleObjectiveQualityAnalyzer.QualityParameter.Hidden = true;
330        singleObjectiveQualityAnalyzer.BestKnownQualityParameter.ActualName = SingleObjectiveProblem.BestKnownQualityParameter.Name;
331        singleObjectiveQualityAnalyzer.BestKnownQualityParameter.Hidden = true;
332      }
333    }
334    private void ParameterizeIterationBasedOperators() {
335      if (Problem != null) {
336        foreach (IIterationBasedOperator op in Problem.Operators.OfType<IIterationBasedOperator>()) {
337          op.IterationsParameter.ActualName = "Iterations";
338          op.IterationsParameter.Hidden = true;
339          op.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
340        }
341      }
342    }
343    private void ParameterizeTerminators() {
344      if (SingleObjectiveProblem != null)
345        qualityTerminator.Parameterize(singleObjectiveQualityAnalyzer.CurrentBestQualityParameter, SingleObjectiveProblem);
346    }
347    private void ParameterizeStochasticOperator(IOperator @operator) {
348      var stochasticOperator = @operator as IStochasticOperator;
349      if (stochasticOperator != null) {
350        stochasticOperator.RandomParameter.ActualName = "Random";
351        stochasticOperator.RandomParameter.Hidden = true;
352      }
353    }
354    private void MaximumEvaluatedSolutions_ValueChanged(object sender, EventArgs e) {
355      MaximumIterations = MaximumEvaluatedSolutions / BatchSize;
356    }
357    private void BatchSize_ValueChanged(object sender, EventArgs e) {
358      MaximumIterations = MaximumEvaluatedSolutions / BatchSize;
359    }
360    #endregion
361
362    #region Updates
363    private void UpdateAnalyzers() {
364      Analyzer.Operators.Clear();
365
366      if (Problem != null) {
367        if (SingleObjectiveProblem != null)
368          Analyzer.Operators.Add(singleObjectiveQualityAnalyzer, singleObjectiveQualityAnalyzer.EnabledByDefault);
369        foreach (var analyzer in Problem.Operators.OfType<IAnalyzer>())
370          Analyzer.Operators.Add(analyzer, analyzer.EnabledByDefault);
371      }
372    }
373    private void UpdateTerminators() {
374      var newTerminators = new Dictionary<ITerminator, bool> {
375        {evaluationsTerminator, !Terminators.Operators.Contains(evaluationsTerminator) || Terminators.Operators.ItemChecked(evaluationsTerminator)},
376        {executionTimeTerminator, Terminators.Operators.Contains(executionTimeTerminator) && Terminators.Operators.ItemChecked(executionTimeTerminator)}
377      };
378      if (Problem != null) {
379        if (SingleObjectiveProblem != null)
380          newTerminators.Add(qualityTerminator, Terminators.Operators.Contains(qualityTerminator) && Terminators.Operators.ItemChecked(qualityTerminator));
381        foreach (var terminator in Problem.Operators.OfType<ITerminator>())
382          newTerminators.Add(terminator, !Terminators.Operators.Contains(terminator) || Terminators.Operators.ItemChecked(terminator));
383      }
384
385      Terminators.Operators.Clear();
386      foreach (var newTerminator in newTerminators)
387        Terminators.Operators.Add(newTerminator.Key, newTerminator.Value);
388    }
389    #endregion
390  }
391}
Note: See TracBrowser for help on using the repository browser.