#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; using System.Collections.Generic; using System.Linq; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Encodings.ConditionActionEncoding { [Item("XCSModel", "Represents a model of XCS")] [StorableClass] public class XCSModel : ReadOnlyItemCollection, IXCSModel { public int ClassifierCount { get { return Count; } } [Storable] private IClassifierComparer comparer; public IClassifierComparer ClassifierComparer { get { return comparer; } set { comparer = value; } } [StorableConstructor] protected XCSModel(bool deserializing) : base(deserializing) { } protected XCSModel(XCSModel original, Cloner cloner) : base(original, cloner) { name = (string)original.name.Clone(); description = (string)original.description.Clone(); if (original.comparer != null) { comparer = (IClassifierComparer)original.comparer.Clone(); } } public override IDeepCloneable Clone(Cloner cloner) { return new XCSModel(this, cloner); } public XCSModel() : base(new ItemCollection()) { } public XCSModel(IItemCollection collection) : base(collection) { this.name = ItemName; this.description = ItemDescription; } public IEnumerable GetAction(IEnumerable classifiers) { foreach (var classifier in classifiers) { yield return GetAction(classifier); } } public IAction GetAction(IInput classifier) { var matchedClassifiers = new ItemCollection(); foreach (var xcsClassifier in this) { if (xcsClassifier.Classifier.MatchInput(classifier)) { matchedClassifiers.Add(xcsClassifier); } } if (matchedClassifiers.Count == 0) { return null; } IDictionary predictionArray = CreatePredictionArray(matchedClassifiers); return predictionArray.OrderByDescending(x => x.Value).First().Key; } private IDictionary CreatePredictionArray(ItemCollection matchedClassifiers) { if (ClassifierComparer == null) { throw new ArgumentException("No classifier comparer specified!"); } var predictionArray = new Dictionary(ClassifierComparer); var fitnessSumPerAction = new Dictionary(ClassifierComparer); foreach (var xcsClassifier in matchedClassifiers) { var action = xcsClassifier.Classifier.Action; if (predictionArray.ContainsKey(action)) { predictionArray[action] += xcsClassifier.Prediction.Value * xcsClassifier.Fitness.Value; fitnessSumPerAction[action] += xcsClassifier.Fitness.Value; } else { predictionArray[action] = xcsClassifier.Prediction.Value * xcsClassifier.Fitness.Value; fitnessSumPerAction[action] = xcsClassifier.Fitness.Value; } } var actions = new List(predictionArray.Keys); foreach (var action in actions) { if (fitnessSumPerAction[action] != 0) { predictionArray[action] = predictionArray[action] / fitnessSumPerAction[action]; } } return predictionArray; } public IXCSSolution CreateConditionActionSolution(IConditionActionProblemData problemData) { return new XCSSolution(this, problemData); } IConditionActionSolution IConditionActionModel.CreateConditionActionSolution(IConditionActionProblemData problemData) { return CreateConditionActionSolution(problemData); } #region INamedItem Members [Storable] protected string name; public string Name { get { return name; } set { if (!CanChangeName) throw new NotSupportedException("Name cannot be changed."); if (!(name.Equals(value) || (value == null) && (name == string.Empty))) { CancelEventArgs e = value == null ? new CancelEventArgs(string.Empty) : new CancelEventArgs(value); OnNameChanging(e); if (!e.Cancel) { name = value == null ? string.Empty : value; OnNameChanged(); } } } } public virtual bool CanChangeName { get { return true; } } [Storable] protected string description; public string Description { get { return description; } set { if (!CanChangeDescription) throw new NotSupportedException("Description cannot be changed."); if (!(description.Equals(value) || (value == null) && (description == string.Empty))) { description = value == null ? string.Empty : value; OnDescriptionChanged(); } } } public virtual bool CanChangeDescription { get { return true; } } public override string ToString() { return Name; } public event EventHandler> NameChanging; protected virtual void OnNameChanging(CancelEventArgs e) { var handler = NameChanging; if (handler != null) handler(this, e); } public event EventHandler NameChanged; protected virtual void OnNameChanged() { var handler = NameChanged; if (handler != null) handler(this, EventArgs.Empty); OnToStringChanged(); } public event EventHandler DescriptionChanged; protected virtual void OnDescriptionChanged() { var handler = DescriptionChanged; if (handler != null) handler(this, EventArgs.Empty); } #endregion } }