Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 15345 was 15252, checked in by gkronber, 7 years ago

#2640: merged r14227 and r14786 from trunk to stable

File size: 17.8 KB
RevLine 
[13580]1#region License Information
2/* HeuristicLab
[14186]3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[13580]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 {
[13952]37  [Item("Random Search Algorithm (RS)", "A random search algorithm.")]
[15252]38  [Creatable(CreatableAttribute.Categories.SingleSolutionAlgorithms, Priority = 150)]
[13580]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    }
[13952]65    private IFixedValueParameter<IntValue> MaximumEvaluatedSolutionsParameter {
66      get { return (IFixedValueParameter<IntValue>)Parameters["MaximumEvaluatedSolutions"]; }
[13580]67    }
68    private IFixedValueParameter<IntValue> BatchSizeParameter {
69      get { return (IFixedValueParameter<IntValue>)Parameters["BatchSize"]; }
70    }
[13952]71    private IFixedValueParameter<IntValue> MaximumIterationsParameter {
72      get { return (IFixedValueParameter<IntValue>)Parameters["MaximumIterations"]; }
[13580]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    }
[13952]91    public int MaximumEvaluatedSolutions {
92      get { return MaximumEvaluatedSolutionsParameter.Value.Value; }
93      set { MaximumEvaluatedSolutionsParameter.Value.Value = value; }
[13580]94    }
95    public int BatchSize {
96      get { return BatchSizeParameter.Value.Value; }
97      set { BatchSizeParameter.Value.Value = value; }
98    }
[13952]99    public int MaximumIterations {
100      get { return MaximumIterationsParameter.Value.Value; }
101      set { MaximumIterationsParameter.Value.Value = value; }
[13580]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)));
[13952]153      Parameters.Add(new FixedValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze the solutions each iteration.", new MultiAnalyzer()));
154      Parameters.Add(new FixedValueParameter<IntValue>("MaximumEvaluatedSolutions", "The number of random solutions the algorithm should evaluate.", new IntValue(1000)));
155      Parameters.Add(new FixedValueParameter<IntValue>("BatchSize", "The number of random solutions that are evaluated (in parallel) per iteration.", new IntValue(100)));
156      Parameters.Add(new FixedValueParameter<IntValue>("MaximumIterations", "The number of iterations that the algorithm will run.", new IntValue(10)) { Hidden = true });
[13580]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();
[13952]168      var iterationsCounter = new IntCounter() { Name = "Increment Iterations" };
[13580]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
[13952]181      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("Iterations", new IntValue(0)));
[13580]182      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("EvaluatedSolutions", new IntValue(0)));
183      variableCreator.Successor = resultsCollector;
184
[13952]185      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Iterations", "The current iteration number."));
[13580]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;
[13952]202      subScopesRemover.Successor = iterationsCounter;
[13580]203
[13952]204      iterationsCounter.ValueParameter.ActualName = "Iterations";
205      iterationsCounter.Increment = new IntValue(1);
206      iterationsCounter.Successor = terminationOperator;
[13580]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
[13952]217      evaluationsTerminator = new ComparisonTerminator<IntValue>("EvaluatedSolutions", ComparisonType.Less, MaximumEvaluatedSolutionsParameter) { Name = "Evaluated solutions." };
[13580]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
[13952]314      MaximumEvaluatedSolutionsParameter.Value.ValueChanged += MaximumEvaluatedSolutions_ValueChanged;
[13580]315      BatchSizeParameter.Value.ValueChanged += BatchSize_ValueChanged;
316    }
317    private void ParameterizeSolutionsCreator() {
318      SolutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
319      SolutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
320    }
321    private void ParameterizeAnalyzers() {
322      singleObjectiveQualityAnalyzer.ResultsParameter.ActualName = "Results";
323      singleObjectiveQualityAnalyzer.ResultsParameter.Hidden = true;
324      singleObjectiveQualityAnalyzer.QualityParameter.Depth = 1;
325
326      if (SingleObjectiveProblem != null) {
327        singleObjectiveQualityAnalyzer.MaximizationParameter.ActualName = SingleObjectiveProblem.MaximizationParameter.Name;
328        singleObjectiveQualityAnalyzer.MaximizationParameter.Hidden = true;
329        singleObjectiveQualityAnalyzer.QualityParameter.ActualName = SingleObjectiveProblem.Evaluator.QualityParameter.ActualName;
330        singleObjectiveQualityAnalyzer.QualityParameter.Hidden = true;
331        singleObjectiveQualityAnalyzer.BestKnownQualityParameter.ActualName = SingleObjectiveProblem.BestKnownQualityParameter.Name;
332        singleObjectiveQualityAnalyzer.BestKnownQualityParameter.Hidden = true;
333      }
334    }
335    private void ParameterizeIterationBasedOperators() {
336      if (Problem != null) {
337        foreach (IIterationBasedOperator op in Problem.Operators.OfType<IIterationBasedOperator>()) {
[13952]338          op.IterationsParameter.ActualName = "Iterations";
[13580]339          op.IterationsParameter.Hidden = true;
[13952]340          op.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
[13580]341        }
342      }
343    }
344    private void ParameterizeTerminators() {
345      if (SingleObjectiveProblem != null)
346        qualityTerminator.Parameterize(singleObjectiveQualityAnalyzer.CurrentBestQualityParameter, SingleObjectiveProblem);
347    }
348    private void ParameterizeStochasticOperator(IOperator @operator) {
349      var stochasticOperator = @operator as IStochasticOperator;
350      if (stochasticOperator != null) {
351        stochasticOperator.RandomParameter.ActualName = "Random";
352        stochasticOperator.RandomParameter.Hidden = true;
353      }
354    }
[13952]355    private void MaximumEvaluatedSolutions_ValueChanged(object sender, EventArgs e) {
356      MaximumIterations = MaximumEvaluatedSolutions / BatchSize;
[13580]357    }
358    private void BatchSize_ValueChanged(object sender, EventArgs e) {
[13952]359      MaximumIterations = MaximumEvaluatedSolutions / BatchSize;
[13580]360    }
361    #endregion
362
363    #region Updates
364    private void UpdateAnalyzers() {
365      Analyzer.Operators.Clear();
366
367      if (Problem != null) {
368        if (SingleObjectiveProblem != null)
369          Analyzer.Operators.Add(singleObjectiveQualityAnalyzer, singleObjectiveQualityAnalyzer.EnabledByDefault);
370        foreach (var analyzer in Problem.Operators.OfType<IAnalyzer>())
371          Analyzer.Operators.Add(analyzer, analyzer.EnabledByDefault);
372      }
373    }
374    private void UpdateTerminators() {
375      var newTerminators = new Dictionary<ITerminator, bool> {
376        {evaluationsTerminator, !Terminators.Operators.Contains(evaluationsTerminator) || Terminators.Operators.ItemChecked(evaluationsTerminator)},
377        {executionTimeTerminator, Terminators.Operators.Contains(executionTimeTerminator) && Terminators.Operators.ItemChecked(executionTimeTerminator)}
378      };
379      if (Problem != null) {
380        if (SingleObjectiveProblem != null)
381          newTerminators.Add(qualityTerminator, Terminators.Operators.Contains(qualityTerminator) && Terminators.Operators.ItemChecked(qualityTerminator));
382        foreach (var terminator in Problem.Operators.OfType<ITerminator>())
383          newTerminators.Add(terminator, !Terminators.Operators.Contains(terminator) || Terminators.Operators.ItemChecked(terminator));
384      }
385
386      Terminators.Operators.Clear();
387      foreach (var newTerminator in newTerminators)
388        Terminators.Operators.Add(newTerminator.Key, newTerminator.Value);
389    }
390    #endregion
391  }
392}
Note: See TracBrowser for help on using the repository browser.