namespace HeuristicLab.Problems.ProgramSynthesis.Push.Analyzer { using System.Linq; using HeuristicLab.Analysis; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Operators; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Problems.ProgramSynthesis.Push.Problem; /// /// An operater that tracks the count of individuals with zero error on the cases /// [Item("IndividualZeroErrorDistributionAnalyzer", "An operater that tracks the distribution of individuals with zero error on the cases")] [StorableClass] public class IndividualZeroErrorDistributionAnalyzer : SingleSuccessorOperator, IIndividualZeroErrorDistributionAnalyzer { private const string RESULTS_PARAMETER_NAME = "Results"; private const string INDIVIDUAL_ZERO_ERROR_PARAMETER_NAME = "ZeroErrorIndividualsPerCaseDistribution"; private const string RESULT_PARAMETER_NAME = "Zero Error Individual Per Case Distribution"; private const string RESULT_PARAMETER_DESCRIPTION = "Relative frequency of instructions aggregated over the whole population."; private const string Y_AXIS_TITLE = "Number of zero error cases"; private const string X_AXIS_TITLE = "Number of individuals"; private const string ROW_NAME = "Cases"; public IndividualZeroErrorDistributionAnalyzer() { Parameters.Add(new LookupParameter( INDIVIDUAL_ZERO_ERROR_PARAMETER_NAME, "The data table to store the count of individuals with zero error.")); Parameters.Add(new LookupParameter( RESULTS_PARAMETER_NAME, "The result collection where the symbol frequencies should be stored.")); Parameters.Add(new ScopeTreeLookupParameter( IntegerVectorPushProblem.CaseQualitiesScopeParameterName, "The quality of every single training case for each individual.")); } [StorableConstructorAttribute] public IndividualZeroErrorDistributionAnalyzer(bool deserializing) : base(deserializing) { } public IndividualZeroErrorDistributionAnalyzer(IndividualZeroErrorDistributionAnalyzer origin, Cloner cloner) : base(origin, cloner) { } public override IDeepCloneable Clone(Cloner cloner) { return new IndividualZeroErrorDistributionAnalyzer(this, cloner); } public bool EnabledByDefault { get { return true; } } public ILookupParameter IndividualZeroErrorDistributionParameter { get { return (ILookupParameter)Parameters[INDIVIDUAL_ZERO_ERROR_PARAMETER_NAME]; } } public ILookupParameter ResultsParameter { get { return (ILookupParameter)Parameters[RESULTS_PARAMETER_NAME]; } } public ILookupParameter> CaseQualitiesParameter { get { return (ILookupParameter>)Parameters[IntegerVectorPushProblem.CaseQualitiesScopeParameterName]; } } public override IOperation Apply() { var caseQualitiesPerIndividual = CaseQualitiesParameter.ActualValue; var individualCount = caseQualitiesPerIndividual.Length; var caseCount = caseQualitiesPerIndividual[0].Length; var results = ResultsParameter.ActualValue; var individualZeroErrorDistribution = IndividualZeroErrorDistributionParameter.ActualValue; if (individualZeroErrorDistribution == null) { individualZeroErrorDistribution = new DataTable( RESULT_PARAMETER_NAME, RESULT_PARAMETER_DESCRIPTION) { VisualProperties = { YAxisTitle = Y_AXIS_TITLE, XAxisTitle = X_AXIS_TITLE, XAxisMinimumFixedValue = 0, XAxisMaximumAuto = true, XAxisMinimumAuto = false, } }; IndividualZeroErrorDistributionParameter.ActualValue = individualZeroErrorDistribution; } if (!results.ContainsKey(RESULT_PARAMETER_NAME)) { results.Add(new Result(RESULT_PARAMETER_NAME, individualZeroErrorDistribution)); } DataRow row; if (!individualZeroErrorDistribution.Rows.TryGetValue(ROW_NAME, out row)) { row = new DataRow(ROW_NAME) { VisualProperties = { StartIndexZero = true, IsVisibleInLegend = false, ChartType = DataRowVisualProperties.DataRowChartType.Histogram, } }; individualZeroErrorDistribution.Rows.Add(row); } var caseCountChanged = row.Values.Count != caseCount; if (caseCountChanged) { row.Values.Clear(); } // key represents the number of cases with zero error // value represents the number of individuals with key cases with zero error var distribution = caseQualitiesPerIndividual .Select(individual => individual.Count(x => x == 0.0)) .GroupBy(x => x) .ToDictionary(x => x.Key, x => x.Count()); for (var i = 0; i < caseCount; i++) { int count; distribution.TryGetValue(i, out count); var x = count / (double)individualCount; if (caseCountChanged) row.Values.Add(x); else row.Values[i] = x; } return base.Apply(); } } }