Free cookie consent management tool by TermsFeed Policy Generator

source: branches/LearningClassifierSystems/HeuristicLab.Encodings.DecisionList/3.3/Variable/DoubleVariable.cs

Last change on this file was 9605, checked in by sforsten, 11 years ago

#1980:

  • set plugin dependencies
  • added smart initialization
  • added hierarchical selection
  • fixed major and minor default rule
  • fixed several smaller bugs
  • some refactoring has been done
File size: 7.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.Optimization.Operators.LCS;
28using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
29
30namespace HeuristicLab.Encodings.DecisionList {
31  [StorableClass]
32  [Item("DoubleVariable", "")]
33  public class DoubleVariable : Variable<double> {
34
35    [Storable]
36    private IDiscretizer discretizer;
37
38    [Storable]
39    private IList<int> curIntervals;
40
41    [Storable]
42    private int maxIntervals;
43
44    [StorableConstructor]
45    protected DoubleVariable(bool deserializing) : base(deserializing) { }
46    protected DoubleVariable(DoubleVariable original, Cloner cloner)
47      : base(original, cloner) {
48      if (original.discretizer != null) {
49        discretizer = (IDiscretizer)original.discretizer.Clone();
50        curIntervals = new List<int>(original.curIntervals);
51      }
52      maxIntervals = original.maxIntervals;
53    }
54    public DoubleVariable(string variableName, int maxIntervals)
55      : base(variableName) {
56      this.maxIntervals = maxIntervals;
57    }
58    public override IDeepCloneable Clone(Cloner cloner) {
59      return new DoubleVariable(this, cloner);
60    }
61
62    public override void Randomize(IRandom random, double onePercentage, IEnumerable<IDiscretizer> discretizers) {
63      discretizer = discretizers.ElementAt(random.Next(0, discretizers.Count()));
64      int microIntervals = discretizer.NumberOfMicroIntervals(variableName);
65      int maxAllowedIntervals = Math.Min(maxIntervals, microIntervals);
66      int numberOfIntervals = 2;
67      if (maxAllowedIntervals > 2) {
68        numberOfIntervals = random.Next(2, maxAllowedIntervals);
69      }
70
71      attributes = new List<bool>(numberOfIntervals);
72      curIntervals = new List<int>(numberOfIntervals);
73
74      for (int i = 0; i < numberOfIntervals - 1; i++) {
75        int microInt = random.Next(1, microIntervals - (numberOfIntervals - i - 1));
76        microIntervals -= microInt;
77        curIntervals.Add(microInt);
78        attributes.Add(random.NextDouble() < onePercentage);
79      }
80      // add last interval
81      curIntervals.Add(microIntervals);
82      attributes.Add(random.NextDouble() < onePercentage);
83    }
84
85    public override double ComputeTheoryLength() {
86      int intervalCount = 0;
87      bool curSet = attributes.First();
88      // first interval started
89      if (curSet) {
90        intervalCount++;
91      }
92      foreach (var attribute in attributes) {
93        if (curSet != attribute) {
94          intervalCount++;
95          curSet = attribute;
96        }
97      }
98      // if the last last interval is not set
99      if (!curSet) {
100        intervalCount--;
101      }
102      return intervalCount;
103    }
104
105    public override bool Match(string input) {
106      return Match(double.Parse(input));
107    }
108
109    public bool Match(double input) {
110      var realCutpoints = GetValuesToCutPoints(discretizer.GetCutPoints(variableName), curIntervals);
111      int pos = 0;
112      while (input >= realCutpoints[pos]) {
113        pos++;
114      }
115      return attributes[pos];
116    }
117
118    private IList<double> GetValuesToCutPoints(IEnumerable<double> cutpoints, IList<int> microIntervals) {
119      var intervalValues = new List<double>();
120      var cutpointList = cutpoints.ToList();
121      int cur = -1;
122      for (int i = 0; i < microIntervals.Count - 1; i++) {
123        cur += microIntervals[i];
124        intervalValues.Add(cutpointList[cur]);
125      }
126      intervalValues.Add(Double.PositiveInfinity);
127      return intervalValues;
128    }
129
130    public override void Split(IRandom random) {
131      // cannot create more than maximal allowed intervals
132      if (curIntervals.Count >= maxIntervals) { return; }
133      int selectedInterval = random.Next(0, curIntervals.Count);
134      // a single microinterval cannot be split
135      if (curIntervals[selectedInterval] <= 1) { return; }
136
137      // split interval
138      int splitPart1 = random.Next(1, curIntervals[selectedInterval]);
139      int splitPart2 = curIntervals[selectedInterval] - splitPart1;
140
141      // resize old interval
142      curIntervals[selectedInterval] = splitPart1;
143      // insert new interval at correct position
144      curIntervals.Insert(selectedInterval + 1, splitPart2);
145
146      // set new interval to the same bool value as old one
147      attributes.Insert(selectedInterval + 1, attributes[selectedInterval]);
148      return;
149    }
150
151    public override void Merge(IRandom random) {
152      // cannot merge a single interval
153      if (curIntervals.Count == 1) { return; }
154      int selectedInterval = random.Next(0, curIntervals.Count);
155      int neighbour;
156      //if selected interval is the leftmost one, the neighbour on the right side is used
157      if (selectedInterval == 0) {
158        neighbour = selectedInterval + 1;
159        //if the selected interval is the rightmost, the neighbour on the left side is used
160      } else if (selectedInterval == curIntervals.Count - 1) {
161        neighbour = selectedInterval - 1;
162      } else {
163        if (random.Next() < 0.5) {
164          neighbour = selectedInterval - 1;
165        } else {
166          neighbour = selectedInterval + 1;
167        }
168      }
169
170      bool value;
171      if (curIntervals[selectedInterval] > curIntervals[neighbour]) {
172        value = attributes[selectedInterval];
173      } else if (curIntervals[selectedInterval] < curIntervals[neighbour]) {
174        value = attributes[neighbour];
175      } else {
176        if (random.Next() < 0.5) {
177          value = attributes[selectedInterval];
178        } else {
179          value = attributes[neighbour];
180        }
181      }
182
183      curIntervals[selectedInterval] += curIntervals[neighbour];
184      curIntervals.RemoveAt(neighbour);
185
186      attributes[selectedInterval] = value;
187      attributes.RemoveAt(neighbour);
188      return;
189    }
190
191    public override void Reinitialize(IRandom random, double onePercentage, IEnumerable<IDiscretizer> descretizers) {
192      Randomize(random, onePercentage, descretizers);
193    }
194
195    public override void SetToMatch(string variableValue) {
196      var value = double.Parse(variableValue);
197      var realCutpoints = GetValuesToCutPoints(discretizer.GetCutPoints(variableName), curIntervals);
198      int pos = 0;
199      while (value >= realCutpoints[pos]) {
200        pos++;
201      }
202      attributes[pos] = true;
203    }
204  }
205}
Note: See TracBrowser for help on using the repository browser.