#region License Information /* HeuristicLab * Copyright (C) 2002-2012 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 System.Linq; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.CombinedIntegerVectorEncoding; using HeuristicLab.Encodings.ConditionActionEncoding; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Problems.DataAnalysis; using HeuristicLab.Problems.Instances; namespace HeuristicLab.Problems.ConditionActionClassification { [StorableClass] public class ConditionActionClassificationProblem : HeuristicOptimizationProblem, IConditionActionProblem, IProblemInstanceConsumer { private const string ClassifierFetcherParameterName = "ClassifierFetcher"; private const string ActionExecuterParameterName = "ActionExecuter"; private const string ActionSetSubsumptionOperatorParameterName = "ActionSetSubsumption"; IXCSEvaluator IConditionActionProblem.Evaluator { get { return Evaluator; } } #region parameter properties public IValueParameter ProblemDataParameter { get { return (IValueParameter)Parameters["ProblemData"]; } } public IValueParameter CoveringSolutionCreatorParameter { get { return (IValueParameter)Parameters["CoveringSolutionCreator"]; } } public IFixedValueParameter ChangeSymbolProbabilityInCoveringParameter { get { return (IFixedValueParameter)Parameters["ChangeSymbolProbabilityInCovering"]; } } public IFixedValueParameter PositiveRewardParameter { get { return (IFixedValueParameter)Parameters["PositiveReward"]; } } public IFixedValueParameter NegativeRewardParameter { get { return (IFixedValueParameter)Parameters["NegativeReward"]; } } public IFixedValueParameter InitialPredictionParameter { get { return (IFixedValueParameter)Parameters["InitialPrediction"]; } } public IFixedValueParameter InitialErrorParameter { get { return (IFixedValueParameter)Parameters["InitialError"]; } } public IFixedValueParameter InitialFitnessParameter { get { return (IFixedValueParameter)Parameters["InitialFitness"]; } } public IFixedValueParameter> PossibleActionsParameter { get { return (IFixedValueParameter>)Parameters["PossibleActions"]; } } public IFixedValueParameter> PossibleActionsConcreteClassParameter { get { return (IFixedValueParameter>)Parameters["PossibleActionsConcreteClass"]; } } public IFixedValueParameter ThetaMinimalNumberOfActionsParameter { get { return (IFixedValueParameter)Parameters["ThetaMinimalNumberOfActions"]; } } #endregion #region properties IParameter IConditionActionProblem.ProblemDataParameter { get { return ProblemDataParameter; } } IConditionActionProblemData IConditionActionProblem.ProblemData { get { return ProblemData; } } public ConditionActionClassificationProblemData ProblemData { get { return ProblemDataParameter.Value; } protected set { ProblemDataParameter.Value = value; if (value != null) { SetProblemDataSpecificParameters(); } } } IParameter IConditionActionProblem.PossibleActionsConcreteClassParameter { get { return PossibleActionsConcreteClassParameter; } } public ItemSet PossibleActionsConcreteClass { get { return PossibleActionsConcreteClassParameter.Value; } } IParameter IConditionActionProblem.PossibleActionsParameter { get { return PossibleActionsParameter; } } //IItemSet IConditionActionProblem.PossibleActions { // get { return PossibleActions; } //} public ItemSet PossibleActions { get { return PossibleActionsParameter.Value; } } public IActionExecuter ActionExecuter { get { return ActionExecuterParameter.Value; } } public ValueParameter ActionExecuterParameter { get { return (ValueParameter)Parameters[ActionExecuterParameterName]; } } IParameter IConditionActionProblem.ActionExecuterParameter { get { return ActionExecuterParameter; } } public ClassifierFetcher ClassifierFetcher { get { return ClassifierFetcherParameter.Value; } } public ValueParameter ClassifierFetcherParameter { get { return (ValueParameter)Parameters[ClassifierFetcherParameterName]; } } IClassifierFetcher IConditionActionProblem.ClassifierFetcher { get { return ClassifierFetcher; } } IParameter IConditionActionProblem.ClassifierFetcherParameter { get { return ClassifierFetcherParameter; } } public ActionSetSubsumptionOperator ActionSetSubsumptionOperator { get { return ActionSetSubsumptionOperatorParameter.Value; } } public ValueParameter ActionSetSubsumptionOperatorParameter { get { return (ValueParameter)Parameters[ActionSetSubsumptionOperatorParameterName]; } } IActionSetSubsumption IConditionActionProblem.ActionSetSubsumptionOperator { get { return ActionSetSubsumptionOperator; } } IParameter IConditionActionProblem.ActionSetSubsumptionOperatorParameter { get { return ActionSetSubsumptionOperatorParameter; } } private IntValue ThetaMinimalNumberOfActions { get { return ThetaMinimalNumberOfActionsParameter.Value; } } IParameter IConditionActionProblem.ThetaMinimalNumberOfActionsParameter { get { return ThetaMinimalNumberOfActionsParameter; } } public ICoveringSolutionCreator CoveringSolutionCreator { get { return CoveringSolutionCreatorParameter.Value; } } IParameter IConditionActionProblem.CoveringSolutionCreatorParameter { get { return CoveringSolutionCreatorParameter; } } private XCSSolutionAnalyzer XCSSolutionAnalyzer { get { return Operators.OfType().FirstOrDefault(); } } #endregion [StorableConstructor] protected ConditionActionClassificationProblem(bool deserializing) : base(deserializing) { } protected ConditionActionClassificationProblem(ConditionActionClassificationProblem original, Cloner cloner) : base(original, cloner) { } public override IDeepCloneable Clone(Cloner cloner) { return new ConditionActionClassificationProblem(this, cloner); } public ConditionActionClassificationProblem() : this(new ConditionActionClassificationProblemData(new Dataset(ConditionActionClassificationProblemData.defaultVariableNames, ConditionActionClassificationProblemData.defaultData), ConditionActionClassificationProblemData.defaultVariableNames.Take(ConditionActionClassificationProblemData.defaultVariableNames.Length - 1), ConditionActionClassificationProblemData.defaultVariableNames.Last().ToEnumerable()), new XCSEvaluator(), new UniformRandomCombinedIntegerVectorCreator(), new CombinedIntegerVectorCoveringCreator()) { } public ConditionActionClassificationProblem(ConditionActionClassificationProblemData problemData, XCSEvaluator evaluator, UniformRandomCombinedIntegerVectorCreator solutionCreator, ICoveringSolutionCreator coveringSolutionCreator) : base(evaluator, solutionCreator) { Parameters.Add(new ValueParameter("ProblemData", "", problemData)); Parameters.Add(new FixedValueParameter("PositiveReward", "", new DoubleValue(1000))); Parameters.Add(new FixedValueParameter("NegativeReward", "", new DoubleValue(0))); Parameters.Add(new FixedValueParameter("InitialPrediction", "Initial Presiction", new DoubleValue(0))); Parameters.Add(new FixedValueParameter("InitialError", "Initial Error", new DoubleValue(0))); Parameters.Add(new FixedValueParameter("InitialFitness", "Initial Fitness", new DoubleValue(0))); Parameters.Add(new ValueParameter(ActionExecuterParameterName, "", new ActionExecuter())); Parameters.Add(new ValueParameter(ClassifierFetcherParameterName, "", new ClassifierFetcher())); Parameters.Add(new FixedValueParameter>("PossibleActions")); Parameters.Add(new FixedValueParameter>("PossibleActionsConcreteClass")); Parameters.Add(new FixedValueParameter("ThetaMinimalNumberOfActions", "Minimal number of actions, which have to be present in the match set, or else covering will occure.", new IntValue(1))); Parameters.Add(new ValueParameter("CoveringSolutionCreator", "", coveringSolutionCreator)); Parameters.Add(new FixedValueParameter("ChangeSymbolProbabilityInCovering", "", new PercentValue(0.5))); Parameters.Add(new ValueParameter(ActionSetSubsumptionOperatorParameterName, "", new ActionSetSubsumptionOperator())); Evaluator.InitialErrorParameter.ActualName = "InitialError"; Evaluator.InitialFitnessParameter.ActualName = "InitialFitness"; Evaluator.InitialPredictionParameter.ActualName = "InitialPrediction"; coveringSolutionCreator.ChangeSymbolProbabilityParameter.ActualName = ChangeSymbolProbabilityInCoveringParameter.Name; coveringSolutionCreator.CoverClassifierParameter.ActualName = ClassifierFetcher.CurrentClassifierToMatchParameter.ActualName; coveringSolutionCreator.CreatedClassifierParameter.ActualName = "CombinedIntegerVector"; ClassifierFetcher.ProblemDataParameter.ActualName = ProblemDataParameter.Name; ActionExecuter.CurrentClassifierToMatchParameter.ActualName = ClassifierFetcher.CurrentClassifierToMatchParameter.ActualName; ActionExecuter.NegativeRewardParameter.ActualName = NegativeRewardParameter.Name; ActionExecuter.PositiveRewardParameter.ActualName = PositiveRewardParameter.Name; ActionSetSubsumptionOperator.ClassifiersParameter.ActualName = "CombinedIntegerVector"; SetProblemDataSpecificParameters(); ThetaMinimalNumberOfActions.Value = PossibleActions.Count; InitializeOperators(); problemData.Changed += new System.EventHandler(problemData_Changed); } private void problemData_Changed(object sender, System.EventArgs e) { SetProblemDataSpecificParameters(); } private void SetProblemDataSpecificParameters() { SolutionCreator.ActionPartLengthParameter.ActualName = ProblemData.ActionLengthParameter.Name; SolutionCreator.LengthParameter.ActualName = ProblemData.LengthParameter.Name; SolutionCreator.BoundsParameter.ActualName = ProblemData.BoundsParameter.Name; SetPossibleActions(); } private void InitializeOperators() { Operators.Add(new XCSSolutionAnalyzer()); ParameterizeAnalyzers(); } private void ParameterizeAnalyzers() { if (XCSSolutionAnalyzer != null) { XCSSolutionAnalyzer.ClassifierParameter.ActualName = SolutionCreator.CombinedIntegerVectorParameter.ActualName; XCSSolutionAnalyzer.PredictionParameter.ActualName = Evaluator.PredictionParameter.ActualName; XCSSolutionAnalyzer.ErrorParameter.ActualName = Evaluator.ErrorParameter.ActualName; XCSSolutionAnalyzer.FitnessParameter.ActualName = Evaluator.FitnessParameter.ActualName; XCSSolutionAnalyzer.ExperienceParameter.ActualName = Evaluator.ExperienceParameter.ActualName; XCSSolutionAnalyzer.AverageActionSetSizeParameter.ActualName = Evaluator.AverageActionSetSizeParameter.ActualName; XCSSolutionAnalyzer.NumerosityParameter.ActualName = Evaluator.NumerosityParameter.ActualName; XCSSolutionAnalyzer.TimestampParameter.ActualName = Evaluator.TimestampParameter.ActualName; XCSSolutionAnalyzer.ProblemDataParameter.ActualName = ProblemDataParameter.Name; XCSSolutionAnalyzer.ResultsParameter.ActualName = "Results"; } } private void SetPossibleActions() { //get bounds of action IntMatrix actionBounds = GetElementsOfBoundsForAction(ProblemData.Bounds, ProblemData.Length.Value, ProblemData.ActionLength.Value); int actionLength = ProblemData.ActionLength.Value; int start = ProblemData.Length.Value - actionLength; int[] elements = new int[actionLength]; int[] curPos = new int[actionLength]; bool done = false; //initialize curPos for (int i = 0; i < actionBounds.Rows; i++) { curPos[i] = actionBounds[i, 0]; } PossibleActions.Clear(); PossibleActionsConcreteClass.Clear(); while (!done) { PossibleActions.Add(new CombinedIntegerVector(curPos, actionLength, actionBounds)); PossibleActionsConcreteClass.Add(new CombinedIntegerVector(curPos, actionLength, actionBounds)); curPos = GetNextAction(curPos, actionBounds, out done); } } private int[] GetNextAction(int[] curPos, IntMatrix actionBounds, out bool done) { int cur = 0; while (cur < curPos.Length) { curPos[cur] += actionBounds.Columns < 3 ? 1 : actionBounds[cur, 2]; if (curPos[cur] >= actionBounds[cur, 1]) { curPos[cur] = actionBounds[cur, 0]; cur++; } else { break; } } done = cur >= curPos.Length; return curPos; } private IntMatrix GetElementsOfBoundsForAction(IntMatrix bounds, int length, int actionPartLength) { IntMatrix actionBounds = new IntMatrix(actionPartLength, bounds.Columns); int start = length - actionPartLength; for (int i = start; i < length; i++) { int pos = i % bounds.Rows; for (int j = 0; j < bounds.Columns; j++) { actionBounds[i - start, j] = bounds[pos, j]; } } return actionBounds; } public void Load(ConditionActionClassificationProblemData data) { Name = data.Name; Description = data.Description; ProblemData = data; } } }