using System; using System.Collections; using System.Collections.Generic; using System.Linq; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction { [StorableClass] public class SparseLinearApproximateStateValueFunction : ParameterizedNamedItem, IStateValueFunction, IStatefulItem { private readonly Dictionary w = new Dictionary(); public IStateFunction StateFunction { get { return ((IValueParameter)Parameters["Feature function"]).Value; } private set { ((IValueParameter)Parameters["Feature function"]).Value = value; } } public SparseLinearApproximateStateValueFunction() : base() { Parameters.Add(new ValueParameter("Feature function", "The function that generates features for value approximation")); } public double Value(object state) { var features = state as IEnumerable>; if (features == null) throw new InvalidProgramException(); return features.Select(t => t.Item2 * GetWeight(t.Item1)).Sum(); } private double GetWeight(string featureId) { double w; this.w.TryGetValue(featureId, out w); return w; } public void Update(object state, double observedQuality) { var features = state as IEnumerable>; if (features == null) throw new InvalidProgramException(); var delta = observedQuality - Value(state); const double alpha = 0.01; foreach (var t in features) { var featureId = t.Item1; var w = t.Item2; this.w[featureId] = GetWeight(featureId) + alpha * delta; } } #region item [StorableConstructor] protected SparseLinearApproximateStateValueFunction(bool deserializing) : base(deserializing) { } protected SparseLinearApproximateStateValueFunction(SparseLinearApproximateStateValueFunction original, Cloner cloner) : base(original, cloner) { w = new Dictionary(original.w); } public override IDeepCloneable Clone(Cloner cloner) { return new SparseLinearApproximateStateValueFunction(this, cloner); } #endregion public void InitializeState() { w.Clear(); } public void ClearState() { w.Clear(); } } }