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 INDIVIDUAL_ZERO_ERROR_HISTORY_PARAMETER_NAME = "ZeroErrorIndividualsPerCaseDistributionHistory"; private const string HISTORY_TABLE_NAME = "Individual Zero Error Distribution History"; 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 = "Individuals Nr"; 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 ValueLookupParameter( INDIVIDUAL_ZERO_ERROR_HISTORY_PARAMETER_NAME, "The data table to store the history.")); 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.")); Parameters.Add(new ValueParameter( "StoreHistory", "True if the history of the analysis should be stored.", new BoolValue(false))); Parameters.Add(new ValueParameter( "UpdateInterval", "The interval in which the analysis should be applied.", new IntValue(1))); Parameters.Add(new ValueParameter( "UpdateCounter", "The value which counts how many times the operator was called since the last update.", new IntValue(0))); IndividualZeroErrorDistributionParameter.Hidden = true; IndividualZeroErrorDistributionHistoryParameter.Hidden = true; ResultsParameter.Hidden = true; UpdateCounterParameter.Hidden = true; } [StorableConstructor] 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 ValueParameter StoreHistoryParameter { get { return (ValueParameter)Parameters["StoreHistory"]; } } public ValueParameter UpdateIntervalParameter { get { return (ValueParameter)Parameters["UpdateInterval"]; } } public ValueParameter UpdateCounterParameter { get { return (ValueParameter)Parameters["UpdateCounter"]; } } public ILookupParameter IndividualZeroErrorDistributionParameter { get { return (ILookupParameter)Parameters[INDIVIDUAL_ZERO_ERROR_PARAMETER_NAME]; } } public ValueLookupParameter IndividualZeroErrorDistributionHistoryParameter { get { return (ValueLookupParameter)Parameters[INDIVIDUAL_ZERO_ERROR_HISTORY_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() { UpdateCounterParameter.Value.Value++; // the analyzer runs periodically, every 'updateInterval' times if (UpdateCounterParameter.Value.Value != UpdateIntervalParameter.Value.Value) return base.Apply(); UpdateCounterParameter.Value.Value = 0; // reset counter 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, YAxisMaximumFixedValue = 1, YAxisMinimumFixedValue = 0, YAxisMaximumAuto = false, YAxisMinimumAuto = false, XAxisMinimumFixedValue = 1, XAxisMaximumFixedValue = individualCount, XAxisMaximumAuto = false, 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.Columns, } }; individualZeroErrorDistribution.Rows.Add(row); } row.Values.Clear(); for (var i = 0; i < caseQualitiesPerIndividual.Length; i++) { var count = caseQualitiesPerIndividual[i].Count(q => q == 0.0); var ratio = count / (double)caseCount; row.Values.Add(ratio); } var storeHistory = StoreHistoryParameter.Value.Value; if (storeHistory) { var history = IndividualZeroErrorDistributionHistoryParameter.ActualValue; if (history == null) { history = new DataTableHistory(); IndividualZeroErrorDistributionHistoryParameter.ActualValue = history; } history.Add((DataTable)individualZeroErrorDistribution.Clone()); if (!results.ContainsKey(HISTORY_TABLE_NAME)) { results.Add(new Result(HISTORY_TABLE_NAME, history)); } else { results[HISTORY_TABLE_NAME].Value = history; } } return base.Apply(); } } }