Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
01/22/16 16:21:20 (9 years ago)
Author:
abeham
Message:

#2457:

  • Fixed bugs in IteratedAlgorithm
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Optimizers/IteratedAlgorithm.cs

    r12890 r13564  
    2323using System.Linq;
    2424using System.Threading;
     25using System.Threading.Tasks;
     26using HeuristicLab.Collections;
    2527using HeuristicLab.Common;
    2628using HeuristicLab.Core;
     
    2931using HeuristicLab.Parameters;
    3032using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    31 using System.Threading.Tasks;
    3233
    3334namespace HeuristicLab.Analysis {
     
    5152
    5253    public override Type ProblemType { get { return typeof(ISingleObjectiveHeuristicOptimizationProblem); } }
    53     public new ISingleObjectiveHeuristicOptimizationProblem Problem {
    54       get { return (ISingleObjectiveHeuristicOptimizationProblem)base.Problem; }
    55       set {
    56         base.Problem = value;
    57         if (Algorithm != null) Algorithm.Problem = Problem;
    58         if (Problem != null) UpdateTargetValueFromBestKnownQuality();
    59       }
    60     }
    6154
    6255    public IValueParameter<TimeSpanValue> MaximumExecutionTimeParameter {
     
    8275    private IValueParameter<IAlgorithm> AlgorithmParameter {
    8376      get { return (IValueParameter<IAlgorithm>)Parameters["Algorithm"]; }
     77    }
     78
     79    private IFixedValueParameter<MultiAnalyzer> AnalyzerParameter {
     80      get { return (IFixedValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
    8481    }
    8582
     
    9289    [Storable]
    9390    private QualityPerClockAnalyzer perClockAnalyzer;
     91    public QualityPerClockAnalyzer PerClockAnalyzer {
     92      get { return perClockAnalyzer; }
     93    }
    9494    [Storable]
    9595    private QualityPerEvaluationsAnalyzer perEvaluationsAnalyzer;
     96    public QualityPerEvaluationsAnalyzer PerEvaluationsAnalyzer {
     97      get { return perEvaluationsAnalyzer; }
     98    }
     99    [Storable]
     100    private BestScopeSolutionAnalyzer bestSolutionAnalyzer;
     101    public BestScopeSolutionAnalyzer BestSolutionAnalyzer {
     102      get { return bestSolutionAnalyzer; }
     103    }
    96104
    97105    public double MoveCostPerSolution {
     
    105113    }
    106114
     115    // algorithm will be set in AfterDeserialization to the value of the parameter
    107116    private IAlgorithm algorithm;
    108117    public IAlgorithm Algorithm {
     
    118127          if (algorithm.ExecutionState != ExecutionState.Prepared)
    119128            algorithm.Prepare(true);
    120           algorithm.Problem = Problem;
     129          if (Problem != null)
     130            algorithm.Problem = Problem;
    121131          RegisterAlgorithmEvents();
    122132          AddAlgorithmAnalyzers();
     
    128138    }
    129139
     140    public MultiAnalyzer Analyzer {
     141      get { return AnalyzerParameter.Value; }
     142    }
     143
    130144    private bool Maximization {
    131       get { return Problem != null && ((IValueParameter<BoolValue>)Problem.MaximizationParameter).Value.Value; }
     145      get { return Problem != null && ((IValueParameter<BoolValue>)((ISingleObjectiveHeuristicOptimizationProblem)Problem).MaximizationParameter).Value.Value; }
    132146    }
    133147
     
    145159        var targetHit = Maximization && bestQuality >= targetValue || !Maximization && bestQuality <= targetValue;
    146160
    147         return timeHit || evalHit || targetHit;
     161        return forceStop || timeHit || evalHit || targetHit;
    148162      }
    149163    }
     
    156170      perClockAnalyzer = cloner.Clone(original.perClockAnalyzer);
    157171      perEvaluationsAnalyzer = cloner.Clone(original.perEvaluationsAnalyzer);
     172      bestSolutionAnalyzer = cloner.Clone(original.bestSolutionAnalyzer);
    158173      algorithm = cloner.Clone(original.algorithm);
    159174      RegisterEventHandlers();
     
    162177      : base() {
    163178      results = new ResultCollection();
     179      Parameters.Add(new FixedValueParameter<MultiAnalyzer>("Analyzer", "Analyzers that should be called in addition to the default algorithm analyzers.", new MultiAnalyzer()));
    164180      Parameters.Add(new OptionalValueParameter<TimeSpanValue>("MaximumExecutionTime", "The maximum wall-clock time that the algorithm should run."));
    165181      Parameters.Add(new OptionalValueParameter<IntValue>("MaximumEvaluations", "The maximum number of function evaluations that the algorithm should run.", new IntValue(100000000)));
     
    171187      perClockAnalyzer = new QualityPerClockAnalyzer();
    172188      perEvaluationsAnalyzer = new QualityPerEvaluationsAnalyzer();
     189      bestSolutionAnalyzer = new BestScopeSolutionAnalyzer();
     190      Analyzer.Operators.Add(perClockAnalyzer, true);
     191      Analyzer.Operators.Add(perEvaluationsAnalyzer, true);
     192      Analyzer.Operators.Add(bestSolutionAnalyzer, StoreSolutionInRun);
    173193
    174194      RegisterEventHandlers();
     
    183203    private void AfterDeserialization() {
    184204      algorithm = AlgorithmParameter.Value;
     205      if (!Parameters.ContainsKey("Analyzer")) {
     206        Parameters.Add(new FixedValueParameter<MultiAnalyzer>("Analyzer", "Analyzers that should be called in addition to the default algorithm analyzers.", new MultiAnalyzer()));
     207        Analyzer.Operators.Add(perClockAnalyzer, true);
     208        Analyzer.Operators.Add(perEvaluationsAnalyzer, true);
     209        if (Algorithm != null && Algorithm.Parameters.ContainsKey("Analyzer")) {
     210          var analyzerParam = Algorithm.Parameters["Analyzer"] as IValueParameter<MultiAnalyzer>;
     211          if (analyzerParam != null) {
     212            analyzerParam.Value.Operators.Remove(perClockAnalyzer);
     213            analyzerParam.Value.Operators.Remove(perEvaluationsAnalyzer);
     214          } else {
     215            var analyzerParam2 = Algorithm.Parameters["Analyzer"] as IValueParameter<IMultiAnalyzer>;
     216            if (analyzerParam2 != null) {
     217              analyzerParam2.Value.Operators.Remove(perClockAnalyzer);
     218              analyzerParam2.Value.Operators.Remove(perEvaluationsAnalyzer);
     219            }
     220          }
     221          AddAlgorithmAnalyzers();
     222        }
     223      }
    185224      RegisterEventHandlers();
    186225    }
     
    188227    #region Register Event Handlers
    189228    protected override void RegisterProblemEvents() {
    190       var bkParam = Problem.BestKnownQualityParameter as IValueParameter<DoubleValue>;
     229      var bkParam = ((ISingleObjectiveHeuristicOptimizationProblem)Problem).BestKnownQualityParameter as IValueParameter<DoubleValue>;
    191230      if (bkParam != null) {
    192231        bkParam.ValueChanged += Problem_BestKnownQualityParameter_ValueChanged;
     
    196235    protected override void DeregisterProblemEvents() {
    197236      base.DeregisterProblemEvents();
    198       var bkParam = Problem.BestKnownQualityParameter as IValueParameter<DoubleValue>;
     237      var bkParam = ((ISingleObjectiveHeuristicOptimizationProblem)Problem).BestKnownQualityParameter as IValueParameter<DoubleValue>;
    199238      if (bkParam != null) {
    200239        bkParam.ValueChanged -= Problem_BestKnownQualityParameter_ValueChanged;
     
    219258      if (Problem != null) RegisterProblemEvents();
    220259      AlgorithmParameter.ValueChanged += AlgorithmParameterOnValueChanged;
     260      StoreSolutionInRunParameter.Value.ValueChanged += StoreSolutionInRunOnValueChanged;
     261      Analyzer.Operators.CollectionReset += AnalyzerOperatorsChanged;
     262      Analyzer.Operators.ItemsAdded += AnalyzerOperatorsChanged;
     263      Analyzer.Operators.ItemsRemoved += AnalyzerOperatorsChanged;
     264      Analyzer.Operators.ItemsReplaced += AnalyzerOperatorsChanged;
     265    }
     266
     267    private bool suppressAnalyzerOperatorEvents = false;
     268
     269    private void AnalyzerOperatorsChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<IAnalyzer>> e) {
     270      if (suppressAnalyzerOperatorEvents) return;
     271      if (!Analyzer.Operators.Contains(perClockAnalyzer)) {
     272        suppressAnalyzerOperatorEvents = true;
     273        try { Analyzer.Operators.Add(perClockAnalyzer, false); } finally { suppressAnalyzerOperatorEvents = false; }
     274      }
     275      if (!Analyzer.Operators.Contains(perEvaluationsAnalyzer)) {
     276        suppressAnalyzerOperatorEvents = true;
     277        try { Analyzer.Operators.Add(perEvaluationsAnalyzer, false); } finally { suppressAnalyzerOperatorEvents = false; }
     278      }
     279      if (!Analyzer.Operators.Contains(bestSolutionAnalyzer)) {
     280        suppressAnalyzerOperatorEvents = true;
     281        try { Analyzer.Operators.Add(bestSolutionAnalyzer, false); } finally { suppressAnalyzerOperatorEvents = false; }
     282      }
     283    }
     284
     285    private void StoreSolutionInRunOnValueChanged(object sender, EventArgs eventArgs) {
     286      Analyzer.Operators.SetItemCheckedState(bestSolutionAnalyzer, StoreSolutionInRun);
    221287    }
    222288
     
    238304      base.Start();
    239305      OnStarted();
    240       var task = Task.Factory.StartNew(Run, null);
    241       task.ContinueWith(t => {
     306      Task.Factory.StartNew(Run, null).ContinueWith(t => {
    242307        try {
    243308          t.Wait();
     
    252317        if (Algorithm.ExecutionState == ExecutionState.Paused) OnPaused();
    253318        else OnStopped();
     319        forceStop = false;
    254320      });
    255321    }
     
    260326    }
    261327
     328    private bool forceStop = false;
    262329    public override void Stop() {
    263330      base.Stop();
    264       Algorithm.Stop();
     331      if (ExecutionState == ExecutionState.Started) {
     332        forceStop = true;
     333        Algorithm.Stop();
     334      } else if (ExecutionState == ExecutionState.Paused) {
     335        RoundupResults();
     336        Algorithm.Prepare(true);
     337        OnStopped();
     338      }
    265339    }
    266340    #endregion
     
    299373        if (Algorithm.ExecutionState == ExecutionState.Paused) return;
    300374
    301         var execTime = ((TimeSpanValue)Results[ExecutionTimeResultName].Value);
    302         var solEvals = ((DoubleValue)Results[EvaluatedSolutionsResultName].Value);
    303         var movEvals = ((DoubleValue)Results[EvaluatedMovesResultName].Value);
    304         var restarts = ((IntValue)Results[RandomRestartsResultName].Value);
    305         var evaluations = ((DoubleValue)Results[EvaluationsResultName].Value);
    306         var bestQuality = ((DoubleValue)Results[BestQualityResultName].Value);
    307         var improvement = false;
    308 
    309         IResult result;
    310         if (Algorithm.Results.TryGetValue(perEvaluationsAnalyzer.EvaluatedSolutionsParameter.ActualName, out result)) {
    311           var evals = ((IntValue)result.Value).Value;
    312           evaluations.Value += evals;
    313           solEvals.Value += evals;
    314         }
    315         if (Algorithm.Results.TryGetValue(perEvaluationsAnalyzer.EvaluatedMovesParameter.ActualName, out result)) {
    316           var evals = ((IntValue)result.Value).Value;
    317           evaluations.Value += MoveCostPerSolution * evals;
    318           movEvals.Value += evals;
    319         }
    320         if (Algorithm.Results.TryGetValue(perEvaluationsAnalyzer.BestQualityParameter.ActualName, out result)) {
    321           var newBestQuality = ((DoubleValue)result.Value).Value;
    322           if (double.IsNaN(bestQuality.Value)
    323               || Maximization && newBestQuality > bestQuality.Value
    324               || !Maximization && newBestQuality < bestQuality.Value) {
    325             bestQuality.Value = newBestQuality;
    326             improvement = true;
    327           }
    328         }
    329         if (Algorithm.Results.TryGetValue(perClockAnalyzer.QualityPerClockParameter.ResultName, out result)) {
    330           UpdateQualityPerClockResult((IndexedDataTable<double>)result.Value, restarts.Value);
    331         }
    332         if (Algorithm.Results.TryGetValue(perEvaluationsAnalyzer.QualityPerEvaluationsParameter.ResultName, out result)) {
    333           UpdateQualityPerEvaluationsResult((IndexedDataTable<double>)result.Value, restarts.Value);
    334         }
    335         if (StoreSolutionInRun) {
    336           foreach (var r in Algorithm.Results) {
    337             if (r.Name.ToLower().EndsWith("solution") && improvement) {
    338               if (!Results.TryGetValue(r.Name, out result))
    339                 Results.Add(new Result(r.Name, (IItem)r.Value.Clone()));
    340               else result.Value = (IItem)r.Value.Clone();
    341             }
    342           }
    343         }
    344 
    345         execTime.Value = ExecutionTime;
     375        RoundupResults();
    346376
    347377        Algorithm.Prepare(true);
    348378      } while (!IsFinished);
     379    }
     380
     381    private void RoundupResults() {
     382      if (Algorithm == null) return;
     383      var execTime = ((TimeSpanValue)Results[ExecutionTimeResultName].Value);
     384      var solEvals = ((DoubleValue)Results[EvaluatedSolutionsResultName].Value);
     385      var movEvals = ((DoubleValue)Results[EvaluatedMovesResultName].Value);
     386      var restarts = ((IntValue)Results[RandomRestartsResultName].Value);
     387      var evaluations = ((DoubleValue)Results[EvaluationsResultName].Value);
     388      var bestQuality = ((DoubleValue)Results[BestQualityResultName].Value);
     389      var improvement = false;
     390
     391      IResult result;
     392      if (Algorithm.Results.TryGetValue(perEvaluationsAnalyzer.EvaluatedSolutionsParameter.ActualName, out result)) {
     393        var evals = ((IntValue)result.Value).Value;
     394        evaluations.Value += evals;
     395        solEvals.Value += evals;
     396      }
     397      if (Algorithm.Results.TryGetValue(perEvaluationsAnalyzer.EvaluatedMovesParameter.ActualName, out result)) {
     398        var evals = ((IntValue)result.Value).Value;
     399        evaluations.Value += MoveCostPerSolution * evals;
     400        movEvals.Value += evals;
     401      }
     402      if (Algorithm.Results.TryGetValue(perEvaluationsAnalyzer.BestQualityParameter.ActualName, out result)) {
     403        var newBestQuality = ((DoubleValue)result.Value).Value;
     404        if (double.IsNaN(bestQuality.Value)
     405            || Maximization && newBestQuality > bestQuality.Value
     406            || !Maximization && newBestQuality < bestQuality.Value) {
     407          bestQuality.Value = newBestQuality;
     408          improvement = true;
     409        }
     410      }
     411      if (Algorithm.Results.TryGetValue(perClockAnalyzer.QualityPerClockParameter.ResultName, out result)) UpdateQualityPerClockResult((IndexedDataTable<double>)result.Value, restarts.Value);
     412      if (Algorithm.Results.TryGetValue(perEvaluationsAnalyzer.QualityPerEvaluationsParameter.ResultName, out result)) UpdateQualityPerEvaluationsResult((IndexedDataTable<double>)result.Value, restarts.Value);
     413      if (StoreSolutionInRun) {
     414        foreach (var r in Algorithm.Results) {
     415          if (r.Name == bestSolutionAnalyzer.BestSolutionResultName || r.Name.ToLower().EndsWith("solution") && improvement) {
     416            if (!Results.TryGetValue(r.Name, out result))
     417              Results.Add(new Result(r.Name, (IItem)r.Value.Clone()));
     418            else result.Value = (IItem)r.Value.Clone();
     419          }
     420        }
     421      }
     422
     423      execTime.Value = ExecutionTime;
    349424    }
    350425
     
    439514
    440515    private void UpdateTargetValueFromBestKnownQuality() {
    441       var bkParam = Problem.BestKnownQualityParameter as IValueParameter<DoubleValue>;
     516      var bkParam = ((ISingleObjectiveHeuristicOptimizationProblem)Problem).BestKnownQualityParameter as IValueParameter<DoubleValue>;
    442517      if (bkParam != null && bkParam.Value != null)
    443518        TargetValueParameter.Value = new DoubleValue(bkParam.Value.Value);
     
    451526      var analyzerParam = Algorithm.Parameters["Analyzer"] as IValueParameter<MultiAnalyzer>;
    452527      if (analyzerParam != null) {
    453         foreach (var analyzer in analyzerParam.Value.Operators.OfType<QualityPerClockAnalyzer>().ToList())
    454           analyzerParam.Value.Operators.Remove(analyzer);
    455         analyzerParam.Value.Operators.Add(perClockAnalyzer);
    456         foreach (var analyzer in analyzerParam.Value.Operators.OfType<QualityPerEvaluationsAnalyzer>().ToList())
    457           analyzerParam.Value.Operators.Remove(analyzer);
    458         analyzerParam.Value.Operators.Add(perEvaluationsAnalyzer);
     528        if (analyzerParam.Value.Operators.Contains(Analyzer)) return;
     529        analyzerParam.Value.Operators.Add(Analyzer, true);
    459530      } else {
    460531        var analyzerParam2 = Algorithm.Parameters["Analyzer"] as IValueParameter<IMultiAnalyzer>;
    461532        if (analyzerParam2 == null) return;
    462         foreach (var analyzer in analyzerParam2.Value.Operators.OfType<QualityPerClockAnalyzer>().ToList())
    463           analyzerParam2.Value.Operators.Remove(analyzer);
    464         analyzerParam2.Value.Operators.Add(perClockAnalyzer);
    465         foreach (var analyzer in analyzerParam2.Value.Operators.OfType<QualityPerEvaluationsAnalyzer>().ToList())
    466           analyzerParam2.Value.Operators.Remove(analyzer);
    467         analyzerParam2.Value.Operators.Add(perEvaluationsAnalyzer);
     533        if (analyzerParam2.Value.Operators.Contains(Analyzer)) return;
     534        analyzerParam2.Value.Operators.Add(Analyzer, true);
    468535      }
    469536    }
     
    474541      var analyzerParam = Algorithm.Parameters["Analyzer"] as IValueParameter<MultiAnalyzer>;
    475542      if (analyzerParam != null) {
    476         analyzerParam.Value.Operators.Remove(perClockAnalyzer);
    477         analyzerParam.Value.Operators.Remove(perEvaluationsAnalyzer);
     543        analyzerParam.Value.Operators.Remove(Analyzer);
    478544      } else {
    479545        var analyzerParam2 = Algorithm.Parameters["Analyzer"] as IValueParameter<IMultiAnalyzer>;
    480546        if (analyzerParam2 != null) {
    481           analyzerParam2.Value.Operators.Remove(perClockAnalyzer);
    482           analyzerParam2.Value.Operators.Remove(perEvaluationsAnalyzer);
     547          analyzerParam2.Value.Operators.Remove(Analyzer);
    483548        }
    484549      }
     
    490555    }
    491556    private void Algorithm_Paused(object sender, EventArgs e) {
     557      if (ExecutionState == ExecutionState.Paused) return;
    492558      algorithmWaitHandle.Set();
    493559    }
    494560    private void Algorithm_Stopped(object sender, EventArgs e) {
     561      if (ExecutionState == ExecutionState.Paused) return;
    495562      algorithmWaitHandle.Set();
    496563    }
     
    519586    protected override void Problem_OperatorsChanged(object sender, EventArgs eventArgs) {
    520587      if (Algorithm != null) AddAlgorithmAnalyzers();
     588    }
     589
     590    protected override void OnProblemChanged() {
     591      base.OnProblemChanged();
     592      if (Algorithm != null) Algorithm.Problem = Problem;
     593      if (Problem != null) UpdateTargetValueFromBestKnownQuality();
    521594    }
    522595
Note: See TracChangeset for help on using the changeset viewer.