namespace HeuristicLab.Problems.ProgramSynthesis.Push.Analyzer { 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("IndividualZeroErrorAnalyzer", "An operater that tracks the count of individuals with zero error on the cases")] [StorableClass] public class IndividualZeroErrorAnalyzer : SingleSuccessorOperator, IIndividualZeroErrorAnalyzer { private const string RESULTS_PARAMETER_NAME = "Results"; private const string INDIVIDUAL_ZERO_ERROR_PARAMETER_NAME = "ZeroErrorIndividualsPerCase"; private const string INDIVIDUAL_ZERO_ERROR_HISTORY_PARAMETER_NAME = INDIVIDUAL_ZERO_ERROR_PARAMETER_NAME + "History"; private const string RESULT_PARAMETER_NAME = "Zero Error Individuals Per Case"; private const string RESULT_PARAMETER_DESCRIPTION = "Relative frequency of instructions aggregated over the whole population."; private const string Y_AXIS_TITLE = "Relative count of zero error individuals"; private const string X_AXIS_TITLE = "Case Nr"; private const string ROW_NAME = "Cases"; private const string HISTORY_TABLE_NAME = "Individual Zero Error history"; public IndividualZeroErrorAnalyzer() { 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))); IndividualZeroErrorParameter.Hidden = true; IndividualZeroErrorHistoryParameter.Hidden = true; ResultsParameter.Hidden = true; UpdateCounterParameter.Hidden = true; } [StorableConstructor] public IndividualZeroErrorAnalyzer(bool deserializing) : base(deserializing) { } public IndividualZeroErrorAnalyzer(IndividualZeroErrorAnalyzer origin, Cloner cloner) : base(origin, cloner) { } public override IDeepCloneable Clone(Cloner cloner) { return new IndividualZeroErrorAnalyzer(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 IndividualZeroErrorParameter { get { return (ILookupParameter)Parameters[INDIVIDUAL_ZERO_ERROR_PARAMETER_NAME]; } } public ValueLookupParameter IndividualZeroErrorHistoryParameter { 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 caseCount = caseQualitiesPerIndividual[0].Length; var results = ResultsParameter.ActualValue; var individualZeroErrorCounts = IndividualZeroErrorParameter.ActualValue; if (individualZeroErrorCounts == null) { individualZeroErrorCounts = new DataTable( RESULT_PARAMETER_NAME, RESULT_PARAMETER_DESCRIPTION) { VisualProperties = { YAxisTitle = Y_AXIS_TITLE, XAxisTitle = X_AXIS_TITLE, YAxisMinimumFixedValue = 0, YAxisMaximumFixedValue = 1, YAxisMinimumAuto = false, YAxisMaximumAuto = false, XAxisMinimumFixedValue = 1, XAxisMaximumFixedValue = caseCount, XAxisMaximumAuto = false, XAxisMinimumAuto = false, } }; IndividualZeroErrorParameter.ActualValue = individualZeroErrorCounts; } if (!results.ContainsKey(RESULT_PARAMETER_NAME)) { results.Add(new Result(RESULT_PARAMETER_NAME, individualZeroErrorCounts)); } DataRow row; if (!individualZeroErrorCounts.Rows.TryGetValue(ROW_NAME, out row)) { row = new DataRow(ROW_NAME) { VisualProperties = { StartIndexZero = true, IsVisibleInLegend = false, ChartType = DataRowVisualProperties.DataRowChartType.Columns, } }; individualZeroErrorCounts.Rows.Add(row); } row.Values.Clear(); for (var i = 0; i < caseCount; i++) { var count = 0; for (var j = 0; j < caseQualitiesPerIndividual.Length; j++) { var caseQuality = caseQualitiesPerIndividual[j][i]; if (caseQuality == 0.0) count++; } var relativeCount = count / (double)caseQualitiesPerIndividual.Length; row.Values.Add(relativeCount); } var storeHistory = StoreHistoryParameter.Value.Value; if (storeHistory) { var history = IndividualZeroErrorHistoryParameter.ActualValue; if (history == null) { history = new DataTableHistory(); IndividualZeroErrorHistoryParameter.ActualValue = history; } history.Add((DataTable)individualZeroErrorCounts.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(); } } }