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();
}
}
}