#region License Information /* HeuristicLab * Copyright (C) 2002-2008 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 System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using HeuristicLab.PluginInfrastructure; using System.Net; using System.ServiceModel; using System.ServiceModel.Description; using System.Linq; using HeuristicLab.Data; using HeuristicLab.Core; using HeuristicLab.Modeling; using HeuristicLab.Modeling.Database; using HeuristicLab.DataAnalysis; namespace HeuristicLab.CEDMA.Server { public class SimpleDispatcher : IDispatcher, IViewable { private class AlgorithmConfiguration { public string name; public ProblemSpecification problemSpecification; } internal event EventHandler Changed; private IModelingDatabase database; public IModelingDatabase Database { get { return database; } } private Dataset dataset; public Dataset Dataset { get { return dataset; } } public IEnumerable TargetVariables { get { return Enumerable.Range(0, Dataset.Columns).Select(x => Dataset.GetVariableName(x)); } } public IEnumerable Variables { get { return TargetVariables; } } private HeuristicLab.Modeling.IAlgorithm[] defaultAlgorithms; public IEnumerable GetAlgorithms(LearningTask task) { switch (task) { case LearningTask.Regression: { return defaultAlgorithms.Where(a => (a as IClassificationAlgorithm) == null && (a as ITimeSeriesAlgorithm) == null); } case LearningTask.Classification: { return defaultAlgorithms.Where(a => (a as IClassificationAlgorithm) != null); } case LearningTask.TimeSeries: { return defaultAlgorithms.Where(a => (a as ITimeSeriesAlgorithm) != null); } default: { return new HeuristicLab.Modeling.IAlgorithm[] { }; } } } private Random random; private Dictionary problemSpecifications; private Dictionary> algorithms; public IEnumerable GetAllowedAlgorithms(string targetVariable) { if (algorithms.ContainsKey(targetVariable)) return algorithms[targetVariable]; else return new HeuristicLab.Modeling.IAlgorithm[] { }; } private Dictionary activeVariables; public IEnumerable AllowedTargetVariables { get { return activeVariables.Where(x => x.Value).Select(x => x.Key); } } private Dictionary> finishedAndDispatchedRuns; private object locker = new object(); public SimpleDispatcher(IModelingDatabase database, Dataset dataset) { this.dataset = dataset; this.database = database; dataset.Changed += (sender, args) => FireChanged(); random = new Random(); activeVariables = new Dictionary(); problemSpecifications = new Dictionary(); algorithms = new Dictionary>(); finishedAndDispatchedRuns = new Dictionary>(); DiscoveryService ds = new DiscoveryService(); defaultAlgorithms = ds.GetInstances(); // PopulateFinishedRuns(); } public HeuristicLab.Modeling.IAlgorithm GetNextJob() { lock (locker) { if (activeVariables.Where(x => x.Value == true).Count() > 0) { string[] targetVariables = (from pair in activeVariables where pair.Value == true select pair.Key).ToArray(); string targetVariable = SelectTargetVariable(targetVariables); HeuristicLab.Modeling.IAlgorithm selectedAlgorithm = SelectAndConfigureAlgorithm(targetVariable); return selectedAlgorithm; } else return null; } } public virtual string SelectTargetVariable(string[] targetVariables) { return targetVariables[random.Next(targetVariables.Length)]; } public HeuristicLab.Modeling.IAlgorithm SelectAndConfigureAlgorithm(string targetVariable) { HeuristicLab.Modeling.IAlgorithm selectedAlgorithm = null; var possibleAlgos = algorithms[targetVariable] .Where(x => ((x is IStochasticAlgorithm) || !AlgorithmFinishedOrDispatched(problemSpecifications[targetVariable], x.Name))); if (possibleAlgos.Count() > 0) selectedAlgorithm = possibleAlgos.ElementAt(random.Next(possibleAlgos.Count())); if (selectedAlgorithm != null) { // create a clone of the algorithm template before setting the parameters selectedAlgorithm = (HeuristicLab.Modeling.IAlgorithm)selectedAlgorithm.Clone(); SetProblemParameters(selectedAlgorithm, problemSpecifications[targetVariable]); if (!(selectedAlgorithm is IStochasticAlgorithm)) AddDispatchedRun(problemSpecifications[targetVariable], selectedAlgorithm.Name); } return selectedAlgorithm; } //private void PopulateFinishedRuns() { // var dispatchedAlgos = from model in Database.GetAllModels() // select new { // TargetVariable = model.TargetVariable.Name, // Algorithm = model.Algorithm.Name, // InputVariables = Database.GetInputVariableResults(model).Select(x => x.Variable.Name).Distinct(), // }; // foreach (var algo in dispatchedAlgos) { // ProblemSpecification spec = new ProblemSpecification(); // spec.TargetVariable = algo.TargetVariable; // foreach (string variable in algo.InputVariables) spec.AddInputVariable(variable); // AddDispatchedRun(spec, algo.Algorithm); // } //} private void SetProblemParameters(HeuristicLab.Modeling.IAlgorithm algo, ProblemSpecification spec) { algo.Dataset = spec.Dataset; algo.TargetVariable = spec.TargetVariable; algo.TrainingSamplesStart = spec.TrainingSamplesStart; algo.TrainingSamplesEnd = spec.TrainingSamplesEnd; algo.ValidationSamplesStart = spec.ValidationSamplesStart; algo.ValidationSamplesEnd = spec.ValidationSamplesEnd; algo.TestSamplesStart = spec.TestSamplesStart; algo.TestSamplesEnd = spec.TestSamplesEnd; List allowedFeatures = new List(); foreach (string inputVariable in spec.InputVariables) { if (inputVariable != spec.TargetVariable) { allowedFeatures.Add(inputVariable); } } if (spec.LearningTask == LearningTask.TimeSeries) { ITimeSeriesAlgorithm timeSeriesAlgo = (ITimeSeriesAlgorithm)algo; timeSeriesAlgo.MinTimeOffset = spec.MinTimeOffset; timeSeriesAlgo.MaxTimeOffset = spec.MaxTimeOffset; timeSeriesAlgo.TrainingSamplesStart = spec.TrainingSamplesStart - spec.MinTimeOffset + 1; // first possible index is 1 because of differential symbol if (spec.AutoRegressive) { allowedFeatures.Add(spec.TargetVariable); } } algo.AllowedVariables = allowedFeatures; } private void AddDispatchedRun(ProblemSpecification specification, string algorithm) { AlgorithmConfiguration conf = new AlgorithmConfiguration(); conf.name = algorithm; conf.problemSpecification = new ProblemSpecification(specification); if (!finishedAndDispatchedRuns.ContainsKey(specification.TargetVariable)) finishedAndDispatchedRuns.Add(specification.TargetVariable, new List()); finishedAndDispatchedRuns[specification.TargetVariable].Add(conf); } private bool AlgorithmFinishedOrDispatched(ProblemSpecification specification, string algoName) { return finishedAndDispatchedRuns.ContainsKey(specification.TargetVariable) && finishedAndDispatchedRuns[specification.TargetVariable].Any(x => algoName == x.name && specification.Equals(x.problemSpecification)); } internal void EnableTargetVariable(string name) { activeVariables[name] = true; } internal void DisableTargetVariable(string name) { activeVariables[name] = false; } public void EnableAlgorithm(string targetVariable, HeuristicLab.Modeling.IAlgorithm algo) { if (!algorithms.ContainsKey(targetVariable)) algorithms.Add(targetVariable, new List()); if (!algorithms[targetVariable].Contains(algo)) algorithms[targetVariable].Add(algo); } public void DisableAlgorithm(string targetVariable, HeuristicLab.Modeling.IAlgorithm algo) { algorithms[targetVariable].Remove(algo); } public ProblemSpecification GetProblemSpecification(string targetVariable) { if (!problemSpecifications.ContainsKey(targetVariable)) problemSpecifications[targetVariable] = CreateDefaultProblemSpecification(targetVariable); return problemSpecifications[targetVariable]; } private ProblemSpecification CreateDefaultProblemSpecification(string targetVariable) { ProblemSpecification spec = new ProblemSpecification(); spec.Dataset = dataset; spec.TargetVariable = targetVariable; spec.LearningTask = LearningTask.Regression; int targetColumn = dataset.GetVariableIndex(targetVariable); // find index of first correct target value int firstValueIndex; for (firstValueIndex = 0; firstValueIndex < dataset.Rows; firstValueIndex++) { double x = dataset.GetValue(firstValueIndex, targetColumn); if (!(double.IsNaN(x) || double.IsInfinity(x))) break; } // find index of last correct target value int lastValueIndex; for (lastValueIndex = dataset.Rows - 1; lastValueIndex > firstValueIndex; lastValueIndex--) { double x = dataset.GetValue(lastValueIndex, targetColumn); if (!(double.IsNaN(x) || double.IsInfinity(x))) break; } int validTargetRange = lastValueIndex - firstValueIndex; spec.TrainingSamplesStart = firstValueIndex; spec.TrainingSamplesEnd = firstValueIndex + (int)Math.Floor(validTargetRange * 0.5); spec.ValidationSamplesStart = spec.TrainingSamplesEnd; spec.ValidationSamplesEnd = firstValueIndex + (int)Math.Floor(validTargetRange * 0.75); spec.TestSamplesStart = spec.ValidationSamplesEnd; spec.TestSamplesEnd = lastValueIndex; return spec; } public void FireChanged() { if (Changed != null) Changed(this, new EventArgs()); } #region IViewable Members public virtual IView CreateView() { return new DispatcherView(this); } #endregion } }