Free cookie consent management tool by TermsFeed Policy Generator

source: branches/1614_GeneralizedQAP/HeuristicLab.OptimizationExpertSystem.Common/3.3/Recommenders/KNearestNeighborModel.cs @ 15736

Last change on this file since 15736 was 15736, checked in by abeham, 6 years ago

#1614: updates from last night ...

File size: 4.3 KB
RevLine 
[13787]1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 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
[15736]22using System;
23using System.Collections.Generic;
24using System.Linq;
[13791]25using HeuristicLab.Collections;
[13878]26using HeuristicLab.Common;
[13787]27using HeuristicLab.Optimization;
28
29namespace HeuristicLab.OptimizationExpertSystem.Common {
30  public class KNearestNeighborModel : IRecommendationModel {
31    private readonly int K;
32    private readonly string[] characteristics;
[13791]33    private readonly Dictionary<IRun, Dictionary<IAlgorithm, double>> performance;
34    private readonly BidirectionalDictionary<int, IRun> problemInstanceMap;
35    private readonly double[] medianValues;
[13787]36
[13791]37    public KNearestNeighborModel(int k, Dictionary<IRun, Dictionary<IAlgorithm, double>> perfData, string[] characteristics) {
[13787]38      this.K = k;
[13791]39      this.performance = perfData;
[13787]40      this.characteristics = characteristics;
[13791]41      problemInstanceMap = new BidirectionalDictionary<int, IRun>();
42      var i = 0;
43      foreach (var pi in perfData.Keys) {
44        problemInstanceMap.Add(i++, pi);
45      }
46      this.medianValues = KnowledgeCenter.GetMedianValues(perfData.Keys.OrderBy(problemInstanceMap.GetBySecond).ToArray(), characteristics);
[13787]47    }
48
[13794]49    public IEnumerable<KeyValuePair<IAlgorithm, double>> GetRanking(IRun problemInstance) {
[13878]50      double[] means, sdevs;
51      var features = KnowledgeCenter.GetFeaturesStandardized(performance.Keys.OrderBy(problemInstanceMap.GetBySecond).ToArray(), characteristics, out means, out sdevs, medianValues);
[13791]52      var feature = KnowledgeCenter.GetFeatures(new [] { problemInstance }, characteristics, medianValues)[0];
[13878]53      for (var f = 0; f < feature.Length; f++) {
54        if (sdevs[f].IsAlmost(0)) feature[f] = 0;
55        else feature[f] = (feature[f] - means[f]) / sdevs[f];
56      }
[15736]57      var dist = features.Select((f, i) => Math.Sqrt(f.Select((g, j) => Math.Sqrt((g - feature[j]) * (g - feature[j]))).Sum())).ToList();
[13791]58      var nearestK = features.Select((f, i) => new { ProblemInstanceIndex = i, Feature = f })
[15736]59                             .OrderBy(x => dist[x.ProblemInstanceIndex]);
[13791]60     
[13803]61      var performances = new Dictionary<IAlgorithm, Performance>();
62
63      var k = 0;
[13791]64      foreach (var next in nearestK) {
[13803]65        if (k >= K) break;
[13791]66        var perfs = performance[problemInstanceMap.GetByFirst(next.ProblemInstanceIndex)];
67        if (perfs.Count == 0) continue;
68       
[13787]69        foreach (var p in perfs) {
[13878]70          var ert = Math.Pow(10, p.Value);
[13803]71          Performance perf;
72          if (!performances.TryGetValue(p.Key, out perf)) {
73            perf = new Performance();
74            performances[p.Key] = perf;
75          }
76          perf.Add(ert);
[13787]77        }
[13803]78
79        k++;
[13787]80      }
81
[13803]82      return performances.Select(x => new { Alg = x.Key, Perf = x.Value.ExpectedRuntime() })
[13787]83                         .OrderBy(x => x.Perf)
[13794]84                         .Select(x => new KeyValuePair<IAlgorithm, double>(x.Alg, x.Perf));
[13787]85    }
[13803]86
87    private class Performance {
88      private readonly List<double> successful;
89      private int runs;
90      public int Fails { get { return runs - successful.Count; } }
91
92      public Performance() {
93        successful = new List<double>();
94      }
95
96      public void Add(double ert) {
97        if (!double.IsInfinity(ert)) successful.Add(ert);
98        runs++;
99      }
100
101      public double ExpectedRuntime() {
102        if (successful.Count == 0) return int.MaxValue;
103        return successful.Average() / (successful.Count / (double)runs);
104      }
105    }
[13787]106  }
107}
Note: See TracBrowser for help on using the repository browser.