source: tags/MetisMQIDemo/src/main/java/weka/core/neighboursearch/kdtrees/KDTreeNodeSplitter.java

Last change on this file was 29, checked in by gnappo, 15 years ago

Taggata versione per la demo e aggiunto branch.

File size: 7.8 KB
Line 
1/*
2 *    This program is free software; you can redistribute it and/or modify
3 *    it under the terms of the GNU General Public License as published by
4 *    the Free Software Foundation; either version 2 of the License, or
5 *    (at your option) any later version.
6 *
7 *    This program is distributed in the hope that it will be useful,
8 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *    GNU General Public License for more details.
11 *
12 *    You should have received a copy of the GNU General Public License
13 *    along with this program; if not, write to the Free Software
14 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/*
18 * KDTreeNodeSplitter.java
19 * Copyright (C) 1999-2007 University of Waikato
20 */
21
22package weka.core.neighboursearch.kdtrees;
23
24import weka.core.EuclideanDistance;
25import weka.core.Instances;
26import weka.core.OptionHandler;
27import weka.core.RevisionHandler;
28import weka.core.RevisionUtils;
29
30import java.io.Serializable;
31import java.util.Enumeration;
32import java.util.Vector;
33
34/**
35 * Class that splits up a KDTreeNode.
36 *
37 * @author Ashraf M. Kibriya (amk14[at-the-rate]cs[dot]waikato[dot]ac[dot]nz)
38 * @version $Revision: 5953 $
39 */
40public abstract class KDTreeNodeSplitter
41  implements Serializable, OptionHandler, RevisionHandler {
42 
43  /** The instances that'll be used for tree construction. */
44  protected Instances m_Instances;
45 
46  /** The distance function used for building the tree. */
47  protected EuclideanDistance m_EuclideanDistance;
48 
49  /**
50   * The master index array that'll be reshuffled as nodes
51   * are split and the tree is constructed.
52   */
53  protected int[] m_InstList;
54 
55  /**
56   * Stores whether if the width of a KDTree
57   * node is normalized or not.
58   */
59  protected boolean m_NormalizeNodeWidth;
60 
61  // Constants
62  /** Index of min value in an array of attributes' range. */
63  public static final int MIN   = EuclideanDistance.R_MIN;
64
65  /** Index of max value in an array of attributes' range. */
66  public static final int MAX   = EuclideanDistance.R_MAX;
67 
68  /** Index of width value (max-min) in an array of attributes' range. */
69  public static final int WIDTH = EuclideanDistance.R_WIDTH;
70
71  /**
72   * default constructor.
73   */
74  public KDTreeNodeSplitter() {
75  }
76 
77  /**
78   * Creates a new instance of KDTreeNodeSplitter.
79   * @param instList Reference of the master index array.
80   * @param insts The set of training instances on which
81   * the tree is built.
82   * @param e The EuclideanDistance object that is used
83   * in tree contruction.
84   */
85  public KDTreeNodeSplitter(int[] instList, Instances insts, EuclideanDistance e) { 
86    m_InstList = instList;
87    m_Instances = insts;
88    m_EuclideanDistance = e;
89  }
90
91  /**
92   * Returns an enumeration describing the available options.
93   *
94   * @return            an enumeration of all the available options.
95   */
96  public Enumeration listOptions() {
97    return new Vector().elements();
98  }
99
100  /**
101   * Parses a given list of options.
102   *
103   * @param options     the list of options as an array of strings
104   * @throws Exception  if an option is not supported
105   */
106  public void setOptions(String[] options) throws Exception {
107  }
108
109  /**
110   * Gets the current settings of the object.
111   *
112   * @return            an array of strings suitable for passing to setOptions
113   */
114  public String[] getOptions() {
115    return new String[0];
116  }
117
118  /**
119   * Checks whether an object of this class has been correctly
120   * initialized. Performs checks to see if all the necessary
121   * things (master index array, training instances, distance
122   * function) have been supplied or not.
123   * @throws Exception If the object has not been correctly
124   * initialized.
125   */
126  protected void correctlyInitialized() throws Exception {
127    if(m_Instances==null)
128      throw new Exception("No instances supplied.");
129    else if(m_InstList==null) 
130      throw new Exception("No instance list supplied.");
131    else if(m_EuclideanDistance==null)
132      throw new Exception("No Euclidean distance function supplied.");
133    else if(m_Instances.numInstances() != m_InstList.length)
134      throw new Exception("The supplied instance list doesn't seem to match " +
135                          "the supplied instances");
136  }
137 
138  /**
139   * Splits a node into two. After splitting two new nodes are created
140   * and correctly initialised. And, node.left and node.right are
141   * set appropriately.
142   * @param node The node to split.
143   * @param numNodesCreated The number of nodes that so far have been
144   * created for the tree, so that the newly created nodes are
145   * assigned correct/meaningful node numbers/ids.
146   * @param nodeRanges The attributes' range for the points inside
147   * the node that is to be split.
148   * @param universe The attributes' range for the whole
149   * point-space.
150   * @throws Exception If there is some problem in splitting the
151   * given node.
152   */
153  public abstract void splitNode(KDTreeNode node, int numNodesCreated, 
154                                 double[][] nodeRanges, double[][] universe) 
155  throws Exception;
156 
157  /**
158   * Sets the training instances on which the tree is (or is
159   * to be) built.
160   * @param inst The training instances.
161   */
162  public void setInstances(Instances inst) {
163    m_Instances = inst;
164  }
165 
166  /**
167   * Sets the master index array containing indices of the
168   * training instances. This array will be rearranged as
169   * the tree is built, so that each node is assigned a
170   * portion in this array which contain the instances
171   * insides the node's region.
172   * @param instList The master index array.
173   */
174  public void setInstanceList(int[] instList) {
175    m_InstList = instList;
176  }
177 
178  /**
179   * Sets the EuclideanDistance object to use for
180   * splitting nodes.
181   * @param func The EuclideanDistance object.
182   */
183  public void setEuclideanDistanceFunction(EuclideanDistance func) {
184    m_EuclideanDistance = func;
185  }
186
187  /**
188   * Sets whether if a nodes region is normalized
189   * or not. If set to true then, when selecting
190   * the widest attribute/dimension for splitting,
191   * the width of each attribute/dimension,
192   * of the points inside the node's region, is
193   * divided by the width of that
194   * attribute/dimension for the whole point-space.
195   * Thus, each attribute/dimension of that node
196   * is normalized.
197   *   
198   * @param normalize Should be true if
199   * normalization is required.
200   */
201  public void setNodeWidthNormalization(boolean normalize) {
202    m_NormalizeNodeWidth = normalize;
203  }
204 
205  /**
206   * Returns the widest dimension. The width of each
207   * dimension (for the points inside the node) is
208   * normalized, if m_NormalizeNodeWidth is set to
209   * true.
210   * @param nodeRanges The attributes' range of the
211   * points inside the node that is to be split.
212   * @param universe The attributes' range for the
213   * whole point-space.
214   * @return The index of the attribute/dimension
215   * in which the points of the node have widest
216   * spread.
217   */
218  protected int widestDim(double[][] nodeRanges, double[][] universe) {
219    final int classIdx = m_Instances.classIndex();
220    double widest = 0.0;
221    int w = -1;
222    if (m_NormalizeNodeWidth) {
223      for (int i = 0; i < nodeRanges.length; i++) {
224        double newWidest = nodeRanges[i][WIDTH] / universe[i][WIDTH];
225        if (newWidest > widest) {
226          if (i == classIdx)
227            continue;
228          widest = newWidest;
229          w = i;
230        }
231      }
232    } else {
233      for (int i = 0; i < nodeRanges.length; i++) {
234        if (nodeRanges[i][WIDTH] > widest) {
235          if (i == classIdx)
236            continue;
237          widest = nodeRanges[i][WIDTH];
238          w = i;
239        }
240      }
241    }
242    return w;
243  }
244 
245  /**
246   * Returns the revision string.
247   *
248   * @return            the revision
249   */
250  public String getRevision() {
251    return RevisionUtils.extract("$Revision: 5953 $");
252  }
253}
Note: See TracBrowser for help on using the repository browser.