Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/23/11 10:00:31 (13 years ago)
Author:
abeham
Message:

#1465

  • updated branch with trunk changes
Location:
branches/histogram
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/histogram

  • branches/histogram/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchImprovementOperator.cs

    r5809 r6046  
    2121
    2222using System;
    23 using System.Collections.Generic;
    2423using System.Linq;
    2524using HeuristicLab.Analysis;
     
    3938  [Item("LocalSearchImprovementOperator", "A local search improvement operator.")]
    4039  [StorableClass]
    41   public class LocalSearchImprovementOperator : SingleSuccessorOperator, ILocalImprovementOperator {
     40  public sealed class LocalSearchImprovementOperator : SingleSuccessorOperator, ILocalImprovementOperator, IStochasticOperator {
     41    #region IGenericLocalImprovementOperator Properties
     42    public Type ProblemType { get { return typeof(ISingleObjectiveHeuristicOptimizationProblem); } }
     43    public IProblem Problem {
     44      get { return problem; }
     45      set {
     46        if (problem != value) {
     47          if (value != null && !(value is ISingleObjectiveHeuristicOptimizationProblem))
     48            throw new ArgumentException("Only problems of type " + ProblemType.ToString() + " can be assigned.");
     49          if (problem != null) DeregisterProblemEventHandlers();
     50          problem = (ISingleObjectiveHeuristicOptimizationProblem)value;
     51          if (problem != null) RegisterProblemEventHandlers();
     52          UpdateProblem();
     53        }
     54      }
     55    }
     56    #endregion
     57
     58    [Storable]
     59    private ISingleObjectiveHeuristicOptimizationProblem problem;
    4260    [Storable]
    4361    private LocalSearchMainLoop loop;
    44 
    4562    [Storable]
    4663    private BestAverageWorstQualityAnalyzer qualityAnalyzer;
    4764
    48     private ConstrainedValueParameter<IMoveGenerator> MoveGeneratorParameter {
     65    #region Parameter Properties
     66    public ConstrainedValueParameter<IMoveGenerator> MoveGeneratorParameter {
    4967      get { return (ConstrainedValueParameter<IMoveGenerator>)Parameters["MoveGenerator"]; }
    5068    }
    51     private ConstrainedValueParameter<IMoveMaker> MoveMakerParameter {
     69    public ConstrainedValueParameter<IMoveMaker> MoveMakerParameter {
    5270      get { return (ConstrainedValueParameter<IMoveMaker>)Parameters["MoveMaker"]; }
    5371    }
    54     private ConstrainedValueParameter<ISingleObjectiveMoveEvaluator> MoveEvaluatorParameter {
     72    public ConstrainedValueParameter<ISingleObjectiveMoveEvaluator> MoveEvaluatorParameter {
    5573      get { return (ConstrainedValueParameter<ISingleObjectiveMoveEvaluator>)Parameters["MoveEvaluator"]; }
    5674    }
    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"]; }
     75    public IValueLookupParameter<IntValue> SampleSizeParameter {
     76      get { return (IValueLookupParameter<IntValue>)Parameters["SampleSize"]; }
    6577    }
    6678    public ValueParameter<MultiAnalyzer> AnalyzerParameter {
    6779      get { return (ValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
    6880    }
    69 
     81    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
     82      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
     83    }
     84    public ILookupParameter<IRandom> RandomParameter {
     85      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
     86    }
     87    #region ILocalImprovementOperator Parameters
     88    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
     89      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
     90    }
     91    public ILookupParameter<IntValue> EvaluatedSolutionsParameter {
     92      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
     93    }
     94    public ILookupParameter<ResultCollection> ResultsParameter {
     95      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
     96    }
     97    #endregion
     98    #endregion
     99
     100    #region Properties
    70101    public IMoveGenerator MoveGenerator {
    71102      get { return MoveGeneratorParameter.Value; }
     
    84115      set { AnalyzerParameter.Value = value; }
    85116    }
     117    #endregion
    86118
    87119    [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)
     120    private LocalSearchImprovementOperator(bool deserializing) : base(deserializing) { }
     121    private LocalSearchImprovementOperator(LocalSearchImprovementOperator original, Cloner cloner)
    94122      : base(original, cloner) {
    95123      this.loop = cloner.Clone(original.loop);
    96124      this.qualityAnalyzer = cloner.Clone(original.qualityAnalyzer);
    97       Initialize();
    98     }
    99     public override IDeepCloneable Clone(Cloner cloner) {
    100       return new LocalSearchImprovementOperator(this, cloner);
     125      this.problem = cloner.Clone(original.problem);
     126      RegisterEventHandlers();
    101127    }
    102128    public LocalSearchImprovementOperator()
    103129      : 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 
    111130      Parameters.Add(new ConstrainedValueParameter<IMoveGenerator>("MoveGenerator", "The operator used to generate moves to the neighborhood of the current solution."));
    112131      Parameters.Add(new ConstrainedValueParameter<IMoveMaker>("MoveMaker", "The operator used to perform a move."));
    113132      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)));
     133      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed.", new IntValue(150)));
     134      Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "Number of moves that MultiMoveGenerators should create. This is ignored for Exhaustive- and SingleMoveGenerators.", new IntValue(300)));
    116135      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The number of evaluated moves."));
    117136      Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze the solution.", new MultiAnalyzer()));
    118 
    119       Initialize();
    120     }
    121 
    122     private void Initialize() {
     137      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The name of the collection where the results are stored."));
     138      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The quality/fitness value of a solution."));
     139      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
     140
     141      loop = new LocalSearchMainLoop();
     142      ((ResultsCollector)((SingleSuccessorOperator)loop.OperatorGraph.InitialOperator).Successor).CollectedValues.Remove(loop.BestLocalQualityParameter.Name);
     143      ParameterizeLSMainLoop();
     144
     145      qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
     146      Analyzer.Operators.Add(qualityAnalyzer);
     147
     148      RegisterEventHandlers();
     149    }
     150
     151    public override IDeepCloneable Clone(Cloner cloner) {
     152      return new LocalSearchImprovementOperator(this, cloner);
     153    }
     154
     155    [StorableHook(HookType.AfterDeserialization)]
     156    private void AfterDeserialization() {
     157      RegisterEventHandlers();
     158    }
     159
     160    #region Event Handler Registration
     161    private void RegisterEventHandlers() {
    123162      MoveGeneratorParameter.ValueChanged += new EventHandler(MoveGeneratorParameter_ValueChanged);
    124     }
    125 
    126     public void OnProblemChanged(IProblem problem) {
    127       UpdateMoveOperators(problem);
     163      if (problem != null)
     164        RegisterProblemEventHandlers();
     165    }
     166
     167    private void RegisterProblemEventHandlers() {
     168      problem.Reset += new EventHandler(problem_Reset);
     169      problem.OperatorsChanged += new EventHandler(problem_OperatorsChanged);
     170    }
     171
     172    private void DeregisterProblemEventHandlers() {
     173      problem.Reset -= new EventHandler(problem_Reset);
     174      problem.OperatorsChanged -= new EventHandler(problem_OperatorsChanged);
     175    }
     176    #endregion
     177
     178    #region Event Handlers
     179    private void MoveGeneratorParameter_ValueChanged(object sender, EventArgs e) {
    128180      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";
     181      ParameterizeLSMainLoop();
     182    }
     183
     184    private void problem_Reset(object sender, EventArgs e) {
     185      UpdateProblem();
     186    }
     187
     188    private void problem_OperatorsChanged(object sender, EventArgs e) {
     189      UpdateProblem();
     190    }
     191    #endregion
     192
     193    #region Parameterize and Update Methods
     194    private void UpdateProblem() {
     195      UpdateMoveOperators();
     196      ChooseMoveOperators();
     197
     198      ParameterizeMoveGenerators();
     199
     200      ParameterizeLSMainLoop();
     201      ParameterizeAnalyzers();
     202    }
     203
     204    private void ParameterizeLSMainLoop() {
     205      loop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
     206      loop.BestLocalQualityParameter.ActualName = QualityParameter.Name;
     207      loop.EvaluatedMovesParameter.ActualName = EvaluatedSolutionsParameter.Name;
     208      loop.IterationsParameter.ActualName = "LocalIterations";
     209      loop.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
     210      loop.MoveEvaluatorParameter.ActualName = MoveEvaluatorParameter.Name;
     211      loop.MoveGeneratorParameter.ActualName = MoveGeneratorParameter.Name;
     212      loop.MoveMakerParameter.ActualName = MoveMakerParameter.Name;
     213      loop.QualityParameter.ActualName = QualityParameter.Name;
     214      loop.RandomParameter.ActualName = RandomParameter.Name;
     215      loop.ResultsParameter.ActualName = ResultsParameter.Name;
     216
     217      if (problem != null) {
     218        loop.BestKnownQualityParameter.ActualName = problem.BestKnownQualityParameter.Name;
     219        loop.MaximizationParameter.ActualName = problem.MaximizationParameter.Name;
     220      }
     221      if (MoveEvaluator != null) {
     222        loop.MoveQualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
     223      }
     224    }
     225
     226    private void ParameterizeAnalyzers() {
     227      qualityAnalyzer.ResultsParameter.ActualName = ResultsParameter.Name;
    140228      if (problem != null) {
    141229        qualityAnalyzer.MaximizationParameter.ActualName = problem.MaximizationParameter.Name;
     
    146234    }
    147235
    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) {
     236    private void UpdateMoveOperators() {
    166237      IMoveGenerator oldMoveGenerator = MoveGenerator;
    167238      IMoveMaker oldMoveMaker = MoveMaker;
     
    171242
    172243      if (problem != null) {
    173         foreach (IMoveGenerator generator in problem.Operators.OfType<IMoveGenerator>().OrderBy(x => x.Name))
     244        foreach (IMultiMoveGenerator generator in problem.Operators.OfType<IMultiMoveGenerator>().OrderBy(x => x.Name))
    174245          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         }
     246        foreach (IExhaustiveMoveGenerator generator in problem.Operators.OfType<IExhaustiveMoveGenerator>().OrderBy(x => x.Name))
     247          MoveGeneratorParameter.ValidValues.Add(generator);
     248
     249        if (oldMoveGenerator != null) {
     250          IMoveGenerator newMoveGenerator = MoveGeneratorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveGenerator.GetType());
     251          if (newMoveGenerator != null) MoveGenerator = newMoveGenerator;
     252        }
     253
     254        ChooseMoveOperators(oldMoveMaker, oldMoveEvaluator);
     255      }
     256    }
     257
     258    private void ChooseMoveOperators(IMoveMaker oldMoveMaker = null, ISingleObjectiveMoveEvaluator oldMoveEvaluator = null) {
     259      if (oldMoveMaker == null) oldMoveMaker = MoveMaker;
     260      if (oldMoveEvaluator == null) oldMoveEvaluator = MoveEvaluator;
     261      MoveMakerParameter.ValidValues.Clear();
     262      MoveEvaluatorParameter.ValidValues.Clear();
     263
     264      if (MoveGenerator != null && Problem != null) {
     265        IMoveGenerator generator = MoveGeneratorParameter.Value;
     266        foreach (IMoveMaker moveMaker in MoveHelper.GetCompatibleMoveMakers(generator, Problem.Operators).OrderBy(x => x.Name))
     267          MoveMakerParameter.ValidValues.Add(moveMaker);
     268        foreach (ISingleObjectiveMoveEvaluator moveEvaluator in MoveHelper.GetCompatibleSingleObjectiveMoveEvaluators(generator, Problem.Operators).OrderBy(x => x.Name))
     269          MoveEvaluatorParameter.ValidValues.Add(moveEvaluator);
     270
    224271        if (oldMoveMaker != null) {
    225           IMoveMaker mm = validMoveMakers.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
     272          IMoveMaker mm = MoveMakerParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
    226273          if (mm != null) MoveMaker = mm;
    227           else MoveMaker = validMoveMakers.FirstOrDefault();
    228         }
    229 
     274        }
    230275        if (oldMoveEvaluator != null) {
    231           ISingleObjectiveMoveEvaluator me = validMoveEvaluators.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
     276          ISingleObjectiveMoveEvaluator me = MoveEvaluatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
    232277          if (me != null) MoveEvaluator = me;
    233           else MoveEvaluator = validMoveEvaluators.FirstOrDefault();
    234278        }
    235279      }
     
    242286    }
    243287
    244     private void ParameterizeMoveGenerators(ISingleObjectiveHeuristicOptimizationProblem problem) {
     288    private void ParameterizeMoveGenerators() {
    245289      if (problem != null) {
    246290        foreach (IMultiMoveGenerator generator in problem.Operators.OfType<IMultiMoveGenerator>())
     
    248292      }
    249293    }
    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     }
     294    #endregion
    262295
    263296    public override IOperation Apply() {
    264       Scope subScope = new Scope();
     297      IScope currentScope = ExecutionContext.Scope;
     298
     299      Scope localScope = new Scope();
    265300      Scope individual = new Scope();
    266301
    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);
     302      foreach (IVariable var in currentScope.Variables)
     303        individual.Variables.Add(var); // add reference to variable otherwise the analyzer fails (it's looking down the tree)
     304
     305      localScope.SubScopes.Add(individual);
     306      currentScope.SubScopes.Add(localScope);
     307      int index = currentScope.SubScopes.Count - 1;
    274308
    275309      SubScopesProcessor processor = new SubScopesProcessor();
     
    279313      remover.SubScopeIndexParameter.Value = new IntValue(index);
    280314
    281       for (int i = 0; i < index; i++) {
    282         processor.Operators.Add(new EmptyOperator());
     315      if (index > 0) {
     316        EmptyOperator eo = new EmptyOperator();
     317        for (int i = 0; i < index - 1; i++) {
     318          processor.Operators.Add(eo);
     319        }
    283320      }
    284321
    285322      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)));
     323      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>(loop.IterationsParameter.ActualName, new IntValue(0)));
     324      variableCreator.CollectedValues.Add(new ValueParameter<DoubleValue>(loop.BestLocalQualityParameter.ActualName, new DoubleValue(0)));
    288325
    289326      variableCreator.Successor = loop;
    290 
    291       loop.EvaluatedMovesParameter.ActualName = EvaluatedSolutionsParameter.ActualName;
    292327
    293328      processor.Operators.Add(variableCreator);
    294329      processor.Successor = remover;
    295330
    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);
     331      OperationCollection next = new OperationCollection(base.Apply());
     332      next.Insert(0, ExecutionContext.CreateChildOperation(processor));
     333
     334      return next;
    302335    }
    303336  }
Note: See TracChangeset for help on using the changeset viewer.