Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchImprovementOperator.cs @ 5959

Last change on this file since 5959 was 5809, checked in by mkommend, 14 years ago

#1418: Reintegrated branch into trunk.

File size: 13.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 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;
34
35namespace HeuristicLab.Algorithms.LocalSearch {
36  /// <summary>
37  /// A local search improvement operator.
38  /// </summary>
39  [Item("LocalSearchImprovementOperator", "A local search improvement operator.")]
40  [StorableClass]
41  public class LocalSearchImprovementOperator : SingleSuccessorOperator, ILocalImprovementOperator {
42    [Storable]
43    private LocalSearchMainLoop loop;
44
45    [Storable]
46    private BestAverageWorstQualityAnalyzer qualityAnalyzer;
47
48    private ConstrainedValueParameter<IMoveGenerator> MoveGeneratorParameter {
49      get { return (ConstrainedValueParameter<IMoveGenerator>)Parameters["MoveGenerator"]; }
50    }
51    private ConstrainedValueParameter<IMoveMaker> MoveMakerParameter {
52      get { return (ConstrainedValueParameter<IMoveMaker>)Parameters["MoveMaker"]; }
53    }
54    private ConstrainedValueParameter<ISingleObjectiveMoveEvaluator> MoveEvaluatorParameter {
55      get { return (ConstrainedValueParameter<ISingleObjectiveMoveEvaluator>)Parameters["MoveEvaluator"]; }
56    }
57    private ValueParameter<IntValue> MaximumIterationsParameter {
58      get { return (ValueParameter<IntValue>)Parameters["MaximumIterations"]; }
59    }
60    private ValueParameter<IntValue> SampleSizeParameter {
61      get { return (ValueParameter<IntValue>)Parameters["SampleSize"]; }
62    }
63    public LookupParameter<IntValue> EvaluatedSolutionsParameter {
64      get { return (LookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
65    }
66    public ValueParameter<MultiAnalyzer> AnalyzerParameter {
67      get { return (ValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
68    }
69
70    public IMoveGenerator MoveGenerator {
71      get { return MoveGeneratorParameter.Value; }
72      set { MoveGeneratorParameter.Value = value; }
73    }
74    public IMoveMaker MoveMaker {
75      get { return MoveMakerParameter.Value; }
76      set { MoveMakerParameter.Value = value; }
77    }
78    public ISingleObjectiveMoveEvaluator MoveEvaluator {
79      get { return MoveEvaluatorParameter.Value; }
80      set { MoveEvaluatorParameter.Value = value; }
81    }
82    public MultiAnalyzer Analyzer {
83      get { return AnalyzerParameter.Value; }
84      set { AnalyzerParameter.Value = value; }
85    }
86
87    [StorableConstructor]
88    protected LocalSearchImprovementOperator(bool deserializing) : base(deserializing) { }
89    [StorableHook(HookType.AfterDeserialization)]
90    private void AfterDeserialization() {
91      Initialize();
92    }
93    protected LocalSearchImprovementOperator(LocalSearchImprovementOperator original, Cloner cloner)
94      : base(original, cloner) {
95      this.loop = cloner.Clone(original.loop);
96      this.qualityAnalyzer = cloner.Clone(original.qualityAnalyzer);
97      Initialize();
98    }
99    public override IDeepCloneable Clone(Cloner cloner) {
100      return new LocalSearchImprovementOperator(this, cloner);
101    }
102    public LocalSearchImprovementOperator()
103      : base() {
104      loop = new LocalSearchMainLoop();
105
106      ResultsCollector rc = (loop.OperatorGraph.InitialOperator as SingleSuccessorOperator).Successor as ResultsCollector;
107      rc.CollectedValues.Remove("BestLocalQuality");
108
109      qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
110
111      Parameters.Add(new ConstrainedValueParameter<IMoveGenerator>("MoveGenerator", "The operator used to generate moves to the neighborhood of the current solution."));
112      Parameters.Add(new ConstrainedValueParameter<IMoveMaker>("MoveMaker", "The operator used to perform a move."));
113      Parameters.Add(new ConstrainedValueParameter<ISingleObjectiveMoveEvaluator>("MoveEvaluator", "The operator used to evaluate a move."));
114      Parameters.Add(new ValueParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed.", new IntValue(150)));
115      Parameters.Add(new ValueParameter<IntValue>("SampleSize", "Number of moves that MultiMoveGenerators should create. This is ignored for Exhaustive- and SingleMoveGenerators.", new IntValue(1500)));
116      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The number of evaluated moves."));
117      Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze the solution.", new MultiAnalyzer()));
118
119      Initialize();
120    }
121
122    private void Initialize() {
123      MoveGeneratorParameter.ValueChanged += new EventHandler(MoveGeneratorParameter_ValueChanged);
124    }
125
126    public void OnProblemChanged(IProblem problem) {
127      UpdateMoveOperators(problem);
128      ChooseMoveOperators();
129
130      ParameterizeMoveGenerators(problem as ISingleObjectiveHeuristicOptimizationProblem);
131      ParameterizeMoveEvaluators(problem as ISingleObjectiveHeuristicOptimizationProblem);
132      ParameterizeMoveMakers(problem as ISingleObjectiveHeuristicOptimizationProblem);
133
134      ParameterizeAnalyzers(problem as ISingleObjectiveHeuristicOptimizationProblem);
135      UpdateAnalyzers(problem as ISingleObjectiveHeuristicOptimizationProblem);
136    }
137
138    void ParameterizeAnalyzers(ISingleObjectiveHeuristicOptimizationProblem problem) {
139      qualityAnalyzer.ResultsParameter.ActualName = "Results";
140      if (problem != null) {
141        qualityAnalyzer.MaximizationParameter.ActualName = problem.MaximizationParameter.Name;
142        if (MoveEvaluator != null)
143          qualityAnalyzer.QualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
144        qualityAnalyzer.BestKnownQualityParameter.ActualName = problem.BestKnownQualityParameter.Name;
145      }
146    }
147
148    void UpdateAnalyzers(ISingleObjectiveHeuristicOptimizationProblem problem) {
149      Analyzer.Operators.Clear();
150      if (problem != null) {
151        foreach (IAnalyzer analyzer in problem.Operators.OfType<IAnalyzer>()) {
152          IAnalyzer clone = analyzer.Clone() as IAnalyzer;
153          foreach (IScopeTreeLookupParameter param in clone.Parameters.OfType<IScopeTreeLookupParameter>())
154            param.Depth = 0;
155          Analyzer.Operators.Add(clone);
156        }
157      }
158      Analyzer.Operators.Add(qualityAnalyzer);
159    }
160
161    void MoveGeneratorParameter_ValueChanged(object sender, EventArgs e) {
162      ChooseMoveOperators();
163    }
164
165    private void UpdateMoveOperators(IProblem problem) {
166      IMoveGenerator oldMoveGenerator = MoveGenerator;
167      IMoveMaker oldMoveMaker = MoveMaker;
168      ISingleObjectiveMoveEvaluator oldMoveEvaluator = MoveEvaluator;
169
170      ClearMoveParameters();
171
172      if (problem != null) {
173        foreach (IMoveGenerator generator in problem.Operators.OfType<IMoveGenerator>().OrderBy(x => x.Name))
174          MoveGeneratorParameter.ValidValues.Add(generator);
175
176        foreach (IMoveMaker maker in problem.Operators.OfType<IMoveMaker>().OrderBy(x => x.Name))
177          MoveMakerParameter.ValidValues.Add(maker);
178
179        foreach (ISingleObjectiveMoveEvaluator evaluator in problem.Operators.OfType<ISingleObjectiveMoveEvaluator>().OrderBy(x => x.Name))
180          MoveEvaluatorParameter.ValidValues.Add(evaluator);
181      }
182
183      if (oldMoveGenerator != null) {
184        IMoveGenerator newMoveGenerator = MoveGeneratorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveGenerator.GetType());
185        if (newMoveGenerator != null) MoveGenerator = newMoveGenerator;
186      }
187      if (MoveGenerator == null) {
188        ClearMoveParameters();
189      }
190
191      if (oldMoveMaker != null) {
192        IMoveMaker mm = MoveMakerParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
193        if (mm != null) MoveMaker = mm;
194      }
195
196      if (oldMoveEvaluator != null) {
197        ISingleObjectiveMoveEvaluator me = MoveEvaluatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
198        if (me != null) MoveEvaluator = me;
199      }
200    }
201
202    private void ChooseMoveOperators() {
203      IMoveMaker oldMoveMaker = MoveMaker;
204      ISingleObjectiveMoveEvaluator oldMoveEvaluator = MoveEvaluator;
205
206      if (MoveGenerator != null) {
207        List<Type> moveTypes = MoveGenerator.GetType().GetInterfaces().Where(x => typeof(IMoveOperator).IsAssignableFrom(x)).ToList();
208        foreach (Type type in moveTypes.ToList()) {
209          if (moveTypes.Any(t => t != type && type.IsAssignableFrom(t)))
210            moveTypes.Remove(type);
211        }
212        List<IMoveMaker> validMoveMakers = new List<IMoveMaker>();
213        List<ISingleObjectiveMoveEvaluator> validMoveEvaluators = new List<ISingleObjectiveMoveEvaluator>();
214
215        foreach (Type type in moveTypes) {
216          var moveMakers = MoveMakerParameter.ValidValues.Where(x => type.IsAssignableFrom(x.GetType())).OrderBy(x => x.Name);
217          foreach (IMoveMaker moveMaker in moveMakers)
218            validMoveMakers.Add(moveMaker);
219
220          var moveEvaluators = MoveEvaluatorParameter.ValidValues.Where(x => type.IsAssignableFrom(x.GetType())).OrderBy(x => x.Name);
221          foreach (ISingleObjectiveMoveEvaluator moveEvaluator in moveEvaluators)
222            validMoveEvaluators.Add(moveEvaluator);
223        }
224        if (oldMoveMaker != null) {
225          IMoveMaker mm = validMoveMakers.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
226          if (mm != null) MoveMaker = mm;
227          else MoveMaker = validMoveMakers.FirstOrDefault();
228        }
229
230        if (oldMoveEvaluator != null) {
231          ISingleObjectiveMoveEvaluator me = validMoveEvaluators.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
232          if (me != null) MoveEvaluator = me;
233          else MoveEvaluator = validMoveEvaluators.FirstOrDefault();
234        }
235      }
236    }
237
238    private void ClearMoveParameters() {
239      MoveGeneratorParameter.ValidValues.Clear();
240      MoveMakerParameter.ValidValues.Clear();
241      MoveEvaluatorParameter.ValidValues.Clear();
242    }
243
244    private void ParameterizeMoveGenerators(ISingleObjectiveHeuristicOptimizationProblem problem) {
245      if (problem != null) {
246        foreach (IMultiMoveGenerator generator in problem.Operators.OfType<IMultiMoveGenerator>())
247          generator.SampleSizeParameter.ActualName = SampleSizeParameter.Name;
248      }
249    }
250    private void ParameterizeMoveEvaluators(ISingleObjectiveHeuristicOptimizationProblem problem) {
251      foreach (ISingleObjectiveMoveEvaluator op in problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
252        op.QualityParameter.ActualName = problem.Evaluator.QualityParameter.ActualName;
253      }
254    }
255    private void ParameterizeMoveMakers(ISingleObjectiveHeuristicOptimizationProblem problem) {
256      foreach (IMoveMaker op in problem.Operators.OfType<IMoveMaker>()) {
257        op.QualityParameter.ActualName = problem.Evaluator.QualityParameter.ActualName;
258        if (MoveEvaluator != null)
259          op.MoveQualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
260      }
261    }
262
263    public override IOperation Apply() {
264      Scope subScope = new Scope();
265      Scope individual = new Scope();
266
267      foreach (Variable var in ExecutionContext.Scope.Variables) {
268        individual.Variables.Add(var);
269      }
270      subScope.SubScopes.Add(individual);
271
272      ExecutionContext.Scope.SubScopes.Add(subScope);
273      int index = subScope.Parent.SubScopes.IndexOf(subScope);
274
275      SubScopesProcessor processor = new SubScopesProcessor();
276      SubScopesRemover remover = new SubScopesRemover();
277
278      remover.RemoveAllSubScopes = false;
279      remover.SubScopeIndexParameter.Value = new IntValue(index);
280
281      for (int i = 0; i < index; i++) {
282        processor.Operators.Add(new EmptyOperator());
283      }
284
285      VariableCreator variableCreator = new VariableCreator();
286      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("LocalIterations", new IntValue(0)));
287      variableCreator.CollectedValues.Add(new ValueParameter<DoubleValue>("BestLocalQuality", new DoubleValue(0)));
288
289      variableCreator.Successor = loop;
290
291      loop.EvaluatedMovesParameter.ActualName = EvaluatedSolutionsParameter.ActualName;
292
293      processor.Operators.Add(variableCreator);
294      processor.Successor = remover;
295
296      IOperation next = base.Apply();
297      if (next as ExecutionContext != null) {
298        remover.Successor = (next as ExecutionContext).Operator;
299      }
300
301      return ExecutionContext.CreateChildOperation(processor);
302    }
303  }
304}
Note: See TracBrowser for help on using the repository browser.