#region License Information /* HeuristicLab * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using HeuristicLab.Collections; using HeuristicLab.Optimization; using System.Collections.Generic; using System.Linq; namespace HeuristicLab.OptimizationExpertSystem.Common { public class KNearestNeighborModel : IRecommendationModel { private readonly int K; private readonly string[] characteristics; private readonly Dictionary> performance; private readonly BidirectionalDictionary problemInstanceMap; private readonly double[] medianValues; public KNearestNeighborModel(int k, Dictionary> perfData, string[] characteristics) { this.K = k; this.performance = perfData; this.characteristics = characteristics; problemInstanceMap = new BidirectionalDictionary(); var i = 0; foreach (var pi in perfData.Keys) { problemInstanceMap.Add(i++, pi); } this.medianValues = KnowledgeCenter.GetMedianValues(perfData.Keys.OrderBy(problemInstanceMap.GetBySecond).ToArray(), characteristics); } public IEnumerable> GetRanking(IRun problemInstance) { var features = KnowledgeCenter.GetFeatures(performance.Keys.OrderBy(problemInstanceMap.GetBySecond).ToArray(), characteristics, medianValues); var feature = KnowledgeCenter.GetFeatures(new [] { problemInstance }, characteristics, medianValues)[0]; var nearestK = features.Select((f, i) => new { ProblemInstanceIndex = i, Feature = f }) .OrderBy(x => x.Feature.Select((f, i) => (f - feature[i]) * (f - feature[i])).Sum()) .Take(K); var performances = new Dictionary>(); foreach (var next in nearestK) { var perfs = performance[problemInstanceMap.GetByFirst(next.ProblemInstanceIndex)]; if (perfs.Count == 0) continue; foreach (var p in perfs) { var ert = p.Value; if (double.IsNaN(ert)) ert = int.MaxValue; List erts; if (!performances.TryGetValue(p.Key, out erts)) { performances[p.Key] = new List() { ert }; ; } else erts.Add(ert); } } return performances.Select(x => new { Alg = x.Key, Perf = x.Value.Average() }) .OrderBy(x => x.Perf) .Select(x => new KeyValuePair(x.Alg, x.Perf)); } } }