#region License Information /* HeuristicLab * Copyright (C) 2002-2019 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.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Operators; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HEAL.Attic; using System.Collections.Generic; using System.Linq; namespace HeuristicLab.Analysis.QualityAnalysis { [Item("QualityDistributionAnalyzer", "Analyzes the distribution of the quality values in that it adds a Histogram of them into the result collection.")] [StorableType("9B339DF1-A9D3-4C9C-B78C-84B764715EB8")] public class QualityDistributionAnalyzer : SingleSuccessorOperator, IAnalyzer, IIterationBasedOperator, ISingleObjectiveOperator { private const string TableDescription = "Shows the quality distributions in the current population."; #region Parameter properties public IScopeTreeLookupParameter QualityParameter { get { return (IScopeTreeLookupParameter)Parameters["Quality"]; } } public IValueLookupParameter ResultsParameter { get { return (IValueLookupParameter)Parameters["Results"]; } } private ValueParameter HistogramNameParameter { get { return (ValueParameter)Parameters["HistogramName"]; } } private ValueParameter StoreHistoryParameter { get { return (ValueParameter)Parameters["StoreHistory"]; } } public ILookupParameter IterationsParameter { get { return (ILookupParameter)Parameters["Iterations"]; } } public IValueLookupParameter MaximumIterationsParameter { get { return (IValueLookupParameter)Parameters["MaximumIterations"]; } } #endregion public virtual bool EnabledByDefault { get { return true; } } public string HistogramName { get { return HistogramNameParameter.Value.Value; } set { HistogramNameParameter.Value.Value = value; } } public bool StoreHistory { get { return StoreHistoryParameter.Value.Value; } set { StoreHistoryParameter.Value.Value = value; } } [StorableConstructor] protected QualityDistributionAnalyzer(StorableConstructorFlag _) : base(_) { } protected QualityDistributionAnalyzer(QualityDistributionAnalyzer original, Cloner cloner) : base(original, cloner) { } public QualityDistributionAnalyzer() : base() { Parameters.Add(new ScopeTreeLookupParameter("Quality", "The value which represents the quality of a solution.")); Parameters.Add(new ValueLookupParameter("Results", "The results collection where the analysis values should be stored.")); Parameters.Add(new FixedValueParameter("HistogramName", "The name of the histogram that gets injected in to the results collection.", new StringValue("Quality Distribution"))); Parameters.Add(new FixedValueParameter("StoreHistory", "True if the history should be stored in addition to the current distribution", new BoolValue(false))); Parameters.Add(new LookupParameter("Iterations", "Optional: A value indicating the current iteration.")); Parameters.Add(new ValueLookupParameter("MaximumIterations", "Unused", new IntValue(-1))); QualityParameter.Hidden = true; ResultsParameter.Hidden = true; IterationsParameter.Hidden = true; MaximumIterationsParameter.Hidden = true; } public override IDeepCloneable Clone(Cloner cloner) { return new QualityDistributionAnalyzer(this, cloner); } public static DataTable PrepareTable(string qualityName = "Quality") { var result = new DataTable("Population Quality Distribution", TableDescription); result.VisualProperties.XAxisTitle = qualityName; result.VisualProperties.YAxisTitle = "Frequency"; var row = new DataRow("QualityDistribution"); row.VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Histogram; result.Rows.Add(row); return result; } public static void UpdateTable(DataTable table, IEnumerable qualities) { var row = table.Rows["QualityDistribution"]; row.Values.Replace(qualities); } public override IOperation Apply() { DataTable qualityDistribution = null; var results = ResultsParameter.ActualValue; if (results.ContainsKey(HistogramName)) { qualityDistribution = (DataTable)results[HistogramName].Value; } else { qualityDistribution = PrepareTable(QualityParameter.ActualName); results.Add(new Result(HistogramName, TableDescription, qualityDistribution)); } UpdateTable(qualityDistribution, QualityParameter.ActualValue.Select(x => x.Value)); if (StoreHistory) { var historyResultName = HistogramName + " History"; DataTableHistory qdHistory = null; if (results.ContainsKey(historyResultName)) { qdHistory = (DataTableHistory)results[historyResultName].Value; } else { qdHistory = new DataTableHistory(); results.Add(new Result(historyResultName, qdHistory)); } var table = (DataTable)qualityDistribution.Clone(); var iteration = IterationsParameter.ActualValue; if (iteration != null) { var iterationName = IterationsParameter.ActualName; if (iterationName.EndsWith("s")) iterationName = iterationName.Remove(iterationName.Length - 1); var appendix = " at " + iterationName + " " + iteration.Value.ToString(); table.Name += appendix; table.Rows["QualityDistribution"].VisualProperties.DisplayName += appendix; } qdHistory.Add(table); } return base.Apply(); } } }