Free cookie consent management tool by TermsFeed Policy Generator

source: branches/WebJobManager/HeuristicLab.Algorithms.RandomSearch/3.3/RandomSearchAlgorithm.cs @ 17687

Last change on this file since 17687 was 13580, checked in by pfleck, 9 years ago

#2571 Implemented Random Search Algorithm.

File size: 17.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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 HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
34using HeuristicLab.Random;
35
36namespace HeuristicLab.Algorithms.RandomSearch {
37  [Item("Random Search Algorithm", "An random search algorithm.")]
38  [Creatable(CreatableAttribute.Categories.Algorithms, Priority = 150)]
39  [StorableClass]
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> NumberOfSamplesParameter {
66      get { return (IFixedValueParameter<IntValue>)Parameters["NumberOfSamples"]; }
67    }
68    private IFixedValueParameter<IntValue> BatchSizeParameter {
69      get { return (IFixedValueParameter<IntValue>)Parameters["BatchSize"]; }
70    }
71    private IFixedValueParameter<IntValue> NumberOfBatchesParameter {
72      get { return (IFixedValueParameter<IntValue>)Parameters["NumberOfBatches"]; }
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 NumberOfSamples {
92      get { return NumberOfSamplesParameter.Value.Value; }
93      set { NumberOfSamplesParameter.Value.Value = value; }
94    }
95    public int BatchSize {
96      get { return BatchSizeParameter.Value.Value; }
97      set { BatchSizeParameter.Value.Value = value; }
98    }
99    public int NumberOfBatches {
100      get { return NumberOfBatchesParameter.Value.Value; }
101      set { NumberOfBatchesParameter.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(bool deserializing)
131      : base(deserializing) { }
132    [StorableHook(HookType.AfterDeserialization)]
133    private void AfterDeserialization() {
134      Initialize();
135    }
136    private RandomSearchAlgorithm(RandomSearchAlgorithm original, Cloner cloner)
137      : base(original, cloner) {
138      singleObjectiveQualityAnalyzer = cloner.Clone(original.singleObjectiveQualityAnalyzer);
139      evaluationsTerminator = cloner.Clone(original.evaluationsTerminator);
140      qualityTerminator = cloner.Clone(original.qualityTerminator);
141      executionTimeTerminator = cloner.Clone(original.executionTimeTerminator);
142      Initialize();
143    }
144    public override IDeepCloneable Clone(Cloner cloner) {
145      return new RandomSearchAlgorithm(this, cloner);
146    }
147
148    public RandomSearchAlgorithm()
149      : base() {
150      #region Add parameters
151      Parameters.Add(new FixedValueParameter<IntValue>("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
152      Parameters.Add(new FixedValueParameter<BoolValue>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
153      Parameters.Add(new FixedValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze all individuals from all layers combined.", new MultiAnalyzer()));
154      Parameters.Add(new FixedValueParameter<IntValue>("NumberOfSamples", "The number of random samples the algorithm should evaluate.", new IntValue(1000)));
155      Parameters.Add(new FixedValueParameter<IntValue>("BatchSize", "The number of random samples that are evaluated (in parallel) until they are analyzed.", new IntValue(100)));
156      Parameters.Add(new FixedValueParameter<IntValue>("NumberOfBatches", "The number batch runs (iterations) that the algorithm will run.", new IntValue(10)) { Hidden = true });
157      Parameters.Add(new FixedValueParameter<MultiTerminator>("Terminator", "The termination criteria that defines if the algorithm should continue or stop.", new MultiTerminator()) { Hidden = true });
158      #endregion
159
160      #region Create operators
161      var randomCreator = new RandomCreator();
162      var variableCreator = new VariableCreator() { Name = "Initialize Variables" };
163      var resultsCollector = new ResultsCollector();
164      var solutionCreator = new SolutionsCreator() { Name = "Create Solutions" };
165      var analyzerPlaceholder = new Placeholder() { Name = "Analyzer (Placeholder)" };
166      var evaluationsCounter = new IntCounter() { Name = "Increment EvaluatedSolutions" };
167      var subScopesRemover = new SubScopesRemover();
168      var batchNumberCounter = new IntCounter() { Name = "Increment BatchNumber" };
169      var terminationOperator = new TerminationOperator();
170      #endregion
171
172      #region Create and parameterize operator graph
173      OperatorGraph.InitialOperator = randomCreator;
174
175      randomCreator.SeedParameter.Value = null;
176      randomCreator.SeedParameter.ActualName = SeedParameter.Name;
177      randomCreator.SetSeedRandomlyParameter.Value = null;
178      randomCreator.SetSeedRandomlyParameter.ActualName = SetSeedRandomlyParameter.Name;
179      randomCreator.Successor = variableCreator;
180
181      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("BatchNumber", new IntValue(0)));
182      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("EvaluatedSolutions", new IntValue(0)));
183      variableCreator.Successor = resultsCollector;
184
185      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("BatchNumber", "The current batch number."));
186      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The current number of evaluated solutions."));
187      resultsCollector.Successor = solutionCreator;
188
189      solutionCreator.NumberOfSolutionsParameter.ActualName = BatchSizeParameter.Name;
190      solutionCreator.ParallelParameter.Value.Value = true;
191      solutionCreator.Successor = evaluationsCounter;
192
193      evaluationsCounter.ValueParameter.ActualName = "EvaluatedSolutions";
194      evaluationsCounter.Increment = null;
195      evaluationsCounter.IncrementParameter.ActualName = BatchSizeParameter.Name;
196      evaluationsCounter.Successor = analyzerPlaceholder;
197
198      analyzerPlaceholder.OperatorParameter.ActualName = AnalyzerParameter.Name;
199      analyzerPlaceholder.Successor = subScopesRemover;
200
201      subScopesRemover.RemoveAllSubScopes = true;
202      subScopesRemover.Successor = batchNumberCounter;
203
204      batchNumberCounter.ValueParameter.ActualName = "BatchNumber";
205      batchNumberCounter.Increment = new IntValue(1);
206      batchNumberCounter.Successor = terminationOperator;
207
208      terminationOperator.TerminatorParameter.ActualName = TerminatorParameter.Name;
209      terminationOperator.ContinueBranch = solutionCreator;
210      #endregion
211
212      #region Create analyzers
213      singleObjectiveQualityAnalyzer = new BestAverageWorstQualityAnalyzer();
214      #endregion
215
216      #region Create terminators
217      evaluationsTerminator = new ComparisonTerminator<IntValue>("EvaluatedSolutions", ComparisonType.Less, NumberOfSamplesParameter) { Name = "Number of Samples" };
218      qualityTerminator = new SingleObjectiveQualityTerminator() { Name = "Quality" };
219      executionTimeTerminator = new ExecutionTimeTerminator(this, new TimeSpanValue(TimeSpan.FromMinutes(5)));
220      #endregion
221
222      #region Parameterize
223      UpdateAnalyzers();
224      ParameterizeAnalyzers();
225      UpdateTerminators();
226      #endregion
227
228      Initialize();
229    }
230    #endregion
231
232    #region Events
233    public override void Prepare() {
234      if (Problem != null)
235        base.Prepare();
236    }
237    protected override void OnProblemChanged() {
238      base.OnProblemChanged();
239      ParameterizeStochasticOperator(Problem.SolutionCreator);
240      foreach (var @operator in Problem.Operators.OfType<IOperator>())
241        ParameterizeStochasticOperator(@operator);
242
243      ParameterizeIterationBasedOperators();
244
245      ParameterizeSolutionsCreator();
246      ParameterizeAnalyzers();
247      ParameterizeTerminators();
248
249      if (SingleObjectiveProblem != null)
250        SingleObjectiveProblem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
251
252      UpdateAnalyzers();
253      UpdateTerminators();
254    }
255
256    protected override void RegisterProblemEvents() {
257      base.RegisterProblemEvents();
258      if (SingleObjectiveProblem != null) {
259        var maximizationParameter = (IValueParameter<BoolValue>)SingleObjectiveProblem.MaximizationParameter;
260        if (maximizationParameter != null) maximizationParameter.ValueChanged += new EventHandler(MaximizationParameter_ValueChanged);
261      }
262    }
263    protected override void DeregisterProblemEvents() {
264      if (SingleObjectiveProblem != null) {
265        var maximizationParameter = (IValueParameter<BoolValue>)SingleObjectiveProblem.MaximizationParameter;
266        if (maximizationParameter != null) maximizationParameter.ValueChanged -= new EventHandler(MaximizationParameter_ValueChanged);
267      }
268      base.DeregisterProblemEvents();
269    }
270
271    protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
272      base.Problem_SolutionCreatorChanged(sender, e);
273      ParameterizeStochasticOperator(Problem.SolutionCreator);
274
275      if (SingleObjectiveProblem != null)
276        SingleObjectiveProblem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
277
278      ParameterizeSolutionsCreator();
279      ParameterizeAnalyzers();
280    }
281    protected override void Problem_EvaluatorChanged(object sender, EventArgs e) {
282      base.Problem_EvaluatorChanged(sender, e);
283      foreach (var @operator in Problem.Operators.OfType<IOperator>())
284        ParameterizeStochasticOperator(@operator);
285
286      UpdateAnalyzers();
287
288      ParameterizeSolutionsCreator();
289    }
290    protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
291      base.Problem_OperatorsChanged(sender, e);
292      ParameterizeIterationBasedOperators();
293      UpdateTerminators();
294    }
295    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
296      ParameterizeAnalyzers();
297    }
298    private void MaximizationParameter_ValueChanged(object sender, EventArgs e) {
299      ParameterizeTerminators();
300    }
301    private void QualityAnalyzer_CurrentBestQualityParameter_NameChanged(object sender, EventArgs e) {
302      ParameterizeTerminators();
303    }
304
305    #endregion
306
307    #region Parameterization
308    private void Initialize() {
309      if (SingleObjectiveProblem != null)
310        SingleObjectiveProblem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
311
312      singleObjectiveQualityAnalyzer.CurrentBestQualityParameter.NameChanged += QualityAnalyzer_CurrentBestQualityParameter_NameChanged;
313
314      NumberOfSamplesParameter.Value.ValueChanged += NumberOfSamples_ValueChanged;
315      BatchSizeParameter.Value.ValueChanged += BatchSize_ValueChanged;
316      NumberOfBatchesParameter.Value.ValueChanged += NumberOfBatches_ValueChanged;
317    }
318    private void ParameterizeSolutionsCreator() {
319      SolutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
320      SolutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
321    }
322    private void ParameterizeAnalyzers() {
323      singleObjectiveQualityAnalyzer.ResultsParameter.ActualName = "Results";
324      singleObjectiveQualityAnalyzer.ResultsParameter.Hidden = true;
325      singleObjectiveQualityAnalyzer.QualityParameter.Depth = 1;
326
327      if (SingleObjectiveProblem != null) {
328        singleObjectiveQualityAnalyzer.MaximizationParameter.ActualName = SingleObjectiveProblem.MaximizationParameter.Name;
329        singleObjectiveQualityAnalyzer.MaximizationParameter.Hidden = true;
330        singleObjectiveQualityAnalyzer.QualityParameter.ActualName = SingleObjectiveProblem.Evaluator.QualityParameter.ActualName;
331        singleObjectiveQualityAnalyzer.QualityParameter.Hidden = true;
332        singleObjectiveQualityAnalyzer.BestKnownQualityParameter.ActualName = SingleObjectiveProblem.BestKnownQualityParameter.Name;
333        singleObjectiveQualityAnalyzer.BestKnownQualityParameter.Hidden = true;
334      }
335    }
336    private void ParameterizeIterationBasedOperators() {
337      if (Problem != null) {
338        foreach (IIterationBasedOperator op in Problem.Operators.OfType<IIterationBasedOperator>()) {
339          op.IterationsParameter.ActualName = "BatchNumber";
340          op.IterationsParameter.Hidden = true;
341          op.MaximumIterationsParameter.ActualName = NumberOfBatchesParameter.Name;
342        }
343      }
344    }
345    private void ParameterizeTerminators() {
346      if (SingleObjectiveProblem != null)
347        qualityTerminator.Parameterize(singleObjectiveQualityAnalyzer.CurrentBestQualityParameter, SingleObjectiveProblem);
348    }
349    private void ParameterizeStochasticOperator(IOperator @operator) {
350      var stochasticOperator = @operator as IStochasticOperator;
351      if (stochasticOperator != null) {
352        stochasticOperator.RandomParameter.ActualName = "Random";
353        stochasticOperator.RandomParameter.Hidden = true;
354      }
355    }
356    private void NumberOfSamples_ValueChanged(object sender, EventArgs e) {
357      NumberOfBatches = NumberOfSamples / BatchSize;
358    }
359    private void BatchSize_ValueChanged(object sender, EventArgs e) {
360      NumberOfBatches = NumberOfSamples / BatchSize;
361    }
362    private void NumberOfBatches_ValueChanged(object sender, EventArgs e) {
363      BatchSize = NumberOfSamples / NumberOfBatches;
364    }
365    #endregion
366
367    #region Updates
368    private void UpdateAnalyzers() {
369      Analyzer.Operators.Clear();
370
371      if (Problem != null) {
372        if (SingleObjectiveProblem != null)
373          Analyzer.Operators.Add(singleObjectiveQualityAnalyzer, singleObjectiveQualityAnalyzer.EnabledByDefault);
374        foreach (var analyzer in Problem.Operators.OfType<IAnalyzer>())
375          Analyzer.Operators.Add(analyzer, analyzer.EnabledByDefault);
376      }
377    }
378    private void UpdateTerminators() {
379      var newTerminators = new Dictionary<ITerminator, bool> {
380        {evaluationsTerminator, !Terminators.Operators.Contains(evaluationsTerminator) || Terminators.Operators.ItemChecked(evaluationsTerminator)},
381        {executionTimeTerminator, Terminators.Operators.Contains(executionTimeTerminator) && Terminators.Operators.ItemChecked(executionTimeTerminator)}
382      };
383      if (Problem != null) {
384        if (SingleObjectiveProblem != null)
385          newTerminators.Add(qualityTerminator, Terminators.Operators.Contains(qualityTerminator) && Terminators.Operators.ItemChecked(qualityTerminator));
386        foreach (var terminator in Problem.Operators.OfType<ITerminator>())
387          newTerminators.Add(terminator, !Terminators.Operators.Contains(terminator) || Terminators.Operators.ItemChecked(terminator));
388      }
389
390      Terminators.Operators.Clear();
391      foreach (var newTerminator in newTerminators)
392        Terminators.Operators.Add(newTerminator.Key, newTerminator.Value);
393    }
394    #endregion
395  }
396}
Note: See TracBrowser for help on using the repository browser.