#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; namespace HeuristicLab.Problems.ConditionActionClassification { [StorableClass] public class ConditionActionClassificationProblem : HeuristicOptimizationProblem, IConditionActionProblem { private const string ClassifierFetcherParameterName = "ClassifierFetcher"; private const string ActionExecuterParameterName = "ActionExecuter"; 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 ThetaMinimalNumberOfActionsParameter { get { return (IFixedValueParameter)Parameters["ThetaMinimalNumberOfActions"]; } } //for test purposes public IFixedValueParameter LengthParameter { get { return (IFixedValueParameter)Parameters["Length"]; } } public IFixedValueParameter ActionPartLengthParameter { get { return (IFixedValueParameter)Parameters["ActionPartLength"]; } } public IFixedValueParameter BoundsParameter { get { return (IFixedValueParameter)Parameters["Bounds"]; } } #endregion #region properties IParameter IConditionActionProblem.ProblemDataParameter { get { return ProblemDataParameter; } } IConditionActionProblemData IConditionActionProblem.ProblemData { get { return ProblemData; } } public ConditionActionClassificationProblemData ProblemData { get { return ProblemDataParameter.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 CombinedIntegerVectorClassifierFetcher 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; } } 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; } } #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 FixedValueParameter("Length", "The operator to create a solution.", new IntValue(7))); Parameters.Add(new FixedValueParameter("ActionPartLength", "The operator to create a solution.", new IntValue(1))); int[,] elements = new int[,] { { 0, 3 }, { 0, 3 }, { 0, 3 }, { 0, 3 }, { 0, 3 }, { 0, 3 }, { 0, 2 } }; Parameters.Add(new FixedValueParameter("Bounds", "The operator to create a solution.", new IntMatrix(elements))); 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 CombinedIntegerVectorClassifierFetcher())); Parameters.Add(new FixedValueParameter>("PossibleActions")); Parameters.Add(new FixedValueParameter("ThetaMinimalNumberOfActions", "Minimal number of actions, which have to be present in the match set, or else covering will occure.")); Parameters.Add(new ValueParameter("CoveringSolutionCreator", "", coveringSolutionCreator)); Parameters.Add(new FixedValueParameter("ChangeSymbolProbabilityInCovering", "", new PercentValue(0.5))); Evaluator.InitialErrorParameter.ActualName = "InitialError"; Evaluator.InitialFitnessParameter.ActualName = "InitialFitness"; Evaluator.InitialPredictionParameter.ActualName = "InitialPrediction"; SolutionCreator.ActionPartLengthParameter.ActualName = ActionPartLengthParameter.Name; SolutionCreator.LengthParameter.ActualName = LengthParameter.Name; SolutionCreator.BoundsParameter.ActualName = BoundsParameter.Name; coveringSolutionCreator.ChangeSymbolProbabilityParameter.ActualName = ChangeSymbolProbabilityInCoveringParameter.Name; coveringSolutionCreator.CoverClassifierParameter.ActualName = ClassifierFetcher.CurrentClassifierToMatchParameter.ActualName; coveringSolutionCreator.CreatedClassifierParameter.ActualName = "CombinedIntegerVector"; ClassifierFetcher.ActionPartLengthParameter.ActualName = ActionPartLengthParameter.Name; ClassifierFetcher.BoundsParameter.ActualName = BoundsParameter.Name; ClassifierFetcher.ProblemDataParameter.ActualName = ProblemDataParameter.Name; ActionExecuter.CurrentClassifierToMatchParameter.ActualName = ClassifierFetcher.CurrentClassifierToMatchParameter.ActualName; ActionExecuter.NegativeRewardParameter.ActualName = NegativeRewardParameter.Name; ActionExecuter.PositiveRewardParameter.ActualName = PositiveRewardParameter.Name; SetPossibleActions(); ThetaMinimalNumberOfActions.Value = PossibleActions.Count; BoundsParameter.ValueChanged += new System.EventHandler(BoundsParameter_ValueChanged); LengthParameter.ValueChanged += new System.EventHandler(LengthParameter_ValueChanged); ActionPartLengthParameter.ValueChanged += new System.EventHandler(ActionPartLengthParameter_ValueChanged); } #region event handler private void ActionPartLengthParameter_ValueChanged(object sender, System.EventArgs e) { SetPossibleActions(); } private void LengthParameter_ValueChanged(object sender, System.EventArgs e) { SetPossibleActions(); } private void BoundsParameter_ValueChanged(object sender, System.EventArgs e) { SetPossibleActions(); } #endregion private void SetPossibleActions() { //get bounds of action IntMatrix actionBounds = GetElementsOfBoundsForAction(BoundsParameter.Value, LengthParameter.Value.Value, ActionPartLengthParameter.Value.Value); int actionLength = ActionPartLengthParameter.Value.Value; int start = LengthParameter.Value.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(); while (!done) { PossibleActions.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; } } }