source: branches/LearningClassifierSystems/HeuristicLab.Encodings.VariableVector/3.3/Variable/StringVariable.cs @ 9467

Last change on this file since 9467 was 9467, checked in by sforsten, 8 years ago

#1980:

  • added ProportionalTournamentSelector for XCS
  • fixed bug: if an initial population is created in XCS, the initial population also creates general classifier, not only specific ones
  • merged r9204:9466 HeuristicLab.Core from trunk to branch
File size: 9.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28
29namespace HeuristicLab.Encodings.VariableVector {
30  [StorableClass]
31  [Item(Name = "StringVariable", Description = "")]
32  public class StringVariable : Variable<string>, IActionVariable {
33
34    public override int VirtualLength {
35      get { return 1; }
36    }
37
38    [Storable]
39    public bool Wildcard { get; set; }
40
41    [Storable]
42    protected IEnumerable<int> possibleFeatures;
43    public IEnumerable<int> PossibleFeatures {
44      get { return possibleFeatures; }
45    }
46
47    [Storable]
48    protected IDictionary<int, string> featureMapping;
49    public IDictionary<int, string> FeatureMapping {
50      get { return featureMapping; }
51    }
52
53    [Storable]
54    protected int currentValue;
55    public int CurrentValue {
56      get { return currentValue; }
57      set {
58        if (!possibleFeatures.Contains(value)) {
59          throw new ArgumentException("Value is not a possible feature of this variable.");
60        }
61        currentValue = value;
62      }
63    }
64
65    public string CurrentStringValue {
66      get { return featureMapping[currentValue]; }
67    }
68
69    [StorableConstructor]
70    protected StringVariable(bool deserializing) : base(deserializing) { }
71    protected StringVariable(StringVariable original, Cloner cloner)
72      : base(original, cloner) {
73      this.possibleFeatures = new List<int>(original.possibleFeatures);
74      this.featureMapping = new Dictionary<int, string>(original.featureMapping);
75      this.Wildcard = original.Wildcard;
76      this.currentValue = original.currentValue;
77    }
78    public StringVariable()
79      : base() {
80      Wildcard = false;
81    }
82    public StringVariable(string variableName, IEnumerable<string> variableValues)
83      : base(variableName) {
84      if (variableValues.Count() != variableValues.Distinct().Count()) {
85        throw new ArgumentException("variableValues have to be distinct.");
86      }
87      featureMapping = new Dictionary<int, string>();
88      var distinctValuesEnumerator = variableValues.Distinct().GetEnumerator();
89      possibleFeatures = Enumerable.Range(0, variableValues.Count());
90      var possibleFeaturesEnumerator = possibleFeatures.GetEnumerator();
91      while (possibleFeaturesEnumerator.MoveNext() && distinctValuesEnumerator.MoveNext()) {
92        featureMapping.Add(possibleFeaturesEnumerator.Current, distinctValuesEnumerator.Current);
93      }
94      Wildcard = false;
95    }
96    public StringVariable(string variableName, IEnumerable<string> variableValues, string currentValue)
97      : this(variableName, variableValues) {
98      int index = 0;
99      foreach (var feature in featureMapping) {
100        if (feature.Equals(currentValue)) {
101          break;
102        }
103        index++;
104      }
105      if (index > featureMapping.Count()) { throw new ArgumentException("variableValues do not contain currentValue."); }
106      CurrentValue = index;
107    }
108    public StringVariable(string variableName, IDictionary<int, string> featureMapping)
109      : base(variableName) {
110      if (featureMapping.Values.Count != featureMapping.Values.Distinct().Count()) {
111        throw new ArgumentException("featureMapping values have to be distinct.");
112      }
113      this.possibleFeatures = featureMapping.Keys;
114      this.featureMapping = featureMapping;
115      Wildcard = false;
116    }
117    public StringVariable(string variableName, IDictionary<int, string> featureMapping, string currentValue)
118      : this(variableName, featureMapping) {
119      bool found = false;
120      foreach (var pair in featureMapping) {
121        if (pair.Value.Equals(currentValue)) {
122          CurrentValue = pair.Key;
123          found = true;
124          break;
125        }
126      }
127      if (!found) {
128        throw new ArgumentException("variableValues do not contain currentValue.");
129      }
130    }
131
132    public override IDeepCloneable Clone(Cloner cloner) {
133      return new StringVariable(this, cloner);
134    }
135
136    public override string ToString() {
137      return Wildcard ? "#" : CurrentStringValue;
138    }
139
140    public override bool MatchInput(string target) {
141      return Wildcard || featureMapping[CurrentValue].Equals(target);
142    }
143
144    public override bool Match(string target) {
145      return MatchInput(target);
146    }
147
148    public override bool MatchVariable(IVariable target) {
149      var targetCast = target as StringVariable;
150      return targetCast != null && this.variableName.Equals(targetCast.VariableName) && Match(targetCast.CurrentStringValue);
151    }
152
153    public override IVariable GetEmptyCopy() {
154      return new StringVariable(variableName, featureMapping);
155    }
156    public override IVariable GetSetCopy() {
157      StringVariable copy = (StringVariable)GetEmptyCopy();
158      copy.Wildcard = this.Wildcard;
159      copy.CurrentValue = this.CurrentValue;
160      return copy;
161    }
162    IActionVariable IActionVariable.GetEmptyCopy() {
163      return (StringVariable)GetEmptyCopy();
164    }
165    IActionVariable IActionVariable.GetSetCopy() {
166      return (StringVariable)GetSetCopy();
167    }
168
169    public void RandomizeAction(IRandom random) {
170      int index = random.Next(possibleFeatures.Count());
171      currentValue = possibleFeatures.ElementAt(index);
172    }
173
174    public override void Randomize(IRandom random, double changeSymbolProbability) {
175      Wildcard = random.NextDouble() < changeSymbolProbability;
176      int index = random.Next(possibleFeatures.Count());
177      currentValue = possibleFeatures.ElementAt(index);
178    }
179
180    public override bool Identical(IVariable target) {
181      var targetCast = target as StringVariable;
182      if (targetCast == null) { return false; }
183      if (variableName != targetCast.variableName || Wildcard != targetCast.Wildcard
184        || currentValue != targetCast.currentValue) { return false; }
185
186      var thisEnumerator = featureMapping.GetEnumerator();
187      var castEnumerator = targetCast.featureMapping.GetEnumerator();
188      while (thisEnumerator.MoveNext() && castEnumerator.MoveNext()) {
189        if (thisEnumerator.Current.Key != castEnumerator.Current.Key ||
190          thisEnumerator.Current.Value != castEnumerator.Current.Value)
191          return false;
192      }
193
194      return !thisEnumerator.MoveNext() && !castEnumerator.MoveNext();
195    }
196
197    public override double GetGenerality() {
198      return Wildcard ? 1 : 0;
199    }
200
201    public override bool IsGreaterThanOrEquallyGeneral(IVariable target) {
202      var targetCast = target as StringVariable;
203      if (targetCast == null) { return false; }
204      return Wildcard || (currentValue == targetCast.currentValue && CurrentStringValue.Equals(targetCast.CurrentStringValue));
205    }
206
207    public override IVariable CrossParentsAtPosition(IVariable parent2, int pos) {
208      var parent2Cast = parent2 as StringVariable;
209      if (parent2Cast == null) { throw new ArgumentException("Argument is not of the correct type."); }
210      if (pos != 0) { throw new ArgumentOutOfRangeException(); }
211      return (StringVariable)parent2.GetSetCopy();
212    }
213
214    public override void Manipulate(IRandom random, string stringValue, int pos) {
215      if (pos != 0) { throw new ArgumentOutOfRangeException(); }
216      Wildcard = !Wildcard;
217      if (!Wildcard) {
218        currentValue = featureMapping.First(x => x.Value.Equals(stringValue)).Key;
219      }
220    }
221
222    public override void Cover(IRandom random, string stringValue, double changeSymbolProbability) {
223      Wildcard = random.NextDouble() < changeSymbolProbability;
224      if (!Wildcard) {
225        currentValue = featureMapping.First(x => x.Value.Equals(stringValue)).Key;
226      }
227    }
228
229    public override int GetHashCode() {
230      int result = 1;
231      int wildcardInt = Wildcard ? 1 : 0;
232      result = 37 * result + wildcardInt;
233      result = 37 * result + currentValue;
234      foreach (var feature in featureMapping) {
235        result = 37 * result + feature.Key;
236        result = 37 * result + feature.Value.GetHashCode();
237      }
238      return result;
239    }
240
241    #region IActionVariable Members
242    public void SetTo(string value) {
243      currentValue = featureMapping.First(x => x.Value.Equals(value)).Key;
244    }
245
246    public IEnumerable<string> GetAllPossibleActions() {
247      return featureMapping.Values;
248    }
249    #endregion
250  }
251}
Note: See TracBrowser for help on using the repository browser.