source: tags/MetisMQIDemo/src/main/java/weka/core/neighboursearch/balltrees/BallNode.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: 11.4 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 * BallNode.java
19 * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand
20 */
21
22package weka.core.neighboursearch.balltrees;
23
24import weka.core.DistanceFunction;
25import weka.core.Instance;
26import weka.core.DenseInstance;
27import weka.core.Instances;
28import weka.core.RevisionHandler;
29import weka.core.RevisionUtils;
30
31import java.io.Serializable;
32
33/**
34 * Class representing a node of a BallTree.
35 *
36 * @author Ashraf M. Kibriya (amk14[at-the-rate]cs[dot]waikato[dot]ac[dot]nz)
37 * @version $Revision: 5987 $
38 */
39public class BallNode
40  implements Serializable, RevisionHandler {
41 
42  /** for serialization. */
43  private static final long serialVersionUID = -8289151861759883510L;
44 
45  /**
46   * The start index of the portion of the master index array,
47   * which stores the indices of the instances/points the node
48   * contains.
49   */
50  public int m_Start;
51 
52  /**
53   * The end index of the portion of the master index array,
54   * which stores indices of the instances/points the node
55   * contains.
56   */
57  public int m_End;
58 
59  /** The number of instances/points in the node. */
60  public int m_NumInstances;
61 
62  /** The node number/id. */
63  public int m_NodeNumber;
64 
65  /** The attribute that splits this node (not
66   * always used). */
67  public int m_SplitAttrib = -1;
68 
69  /** The value of m_SpiltAttrib that splits this
70   * node (not always used).
71   */
72  public double m_SplitVal = -1;
73 
74  /** The left child of the node. */
75  public BallNode m_Left = null;
76 
77  /** The right child of the node. */
78  public BallNode m_Right = null;
79 
80  /**
81   * The pivot/centre of the ball.
82   */
83  protected Instance m_Pivot;
84 
85  /** The radius of this ball (hyper sphere). */
86  protected double m_Radius;
87 
88  /**
89   * Constructor.
90   * @param nodeNumber The node's number/id.
91   */
92  public BallNode(int nodeNumber) {
93    m_NodeNumber = nodeNumber;
94  }
95 
96  /**
97   * Creates a new instance of BallNode.
98   * @param start The begining index of the portion of
99   * the master index array belonging to this node.
100   * @param end The end index of the portion of the
101   * master index array belonging to this node.
102   * @param nodeNumber The node's number/id.
103   */
104  public BallNode(int start, int end, int nodeNumber) {
105    m_Start = start;
106    m_End = end;
107    m_NodeNumber = nodeNumber;
108    m_NumInstances = end - start + 1;
109  }
110 
111  /**
112   * Creates a new instance of BallNode.
113   * @param start The begining index of the portion of
114   * the master index array belonging to this node.
115   * @param end The end index of the portion of the
116   * master index array belonging to this node.
117   * @param nodeNumber The node's number/id.
118   * @param pivot The pivot/centre of the node's ball.
119   * @param radius The radius of the node's ball.
120   */
121  public BallNode(int start, int end, int nodeNumber, Instance pivot, double radius) {
122    m_Start = start;
123    m_End = end;
124    m_NodeNumber = nodeNumber; 
125    m_Pivot = pivot;
126    m_Radius = radius;
127    m_NumInstances = end - start + 1;
128  }
129 
130  /**
131   * Returns true if the node is a leaf node (if
132   * both its left and right child are null).
133   * @return true if the node is a leaf node.
134   */
135  public boolean isALeaf() {
136    return (m_Left==null && m_Right==null);
137  }
138 
139  /**
140   * Sets the the start and end index of the
141   * portion of the master index array that is
142   * assigned to this node. 
143   * @param start The start index of the
144   * master index array.
145   * @param end The end index of the master
146   * indext array.
147   */
148  public void setStartEndIndices(int start, int end) {
149    m_Start = start;
150    m_End = end;
151    m_NumInstances = end - start + 1;   
152  }
153
154  /**
155   * Sets the pivot/centre of this nodes
156   * ball.
157   * @param pivot The centre/pivot.
158   */
159  public void setPivot(Instance pivot) {
160    m_Pivot = pivot;
161  }
162 
163  /**
164   * Returns the pivot/centre of the
165   * node's ball.
166   * @return The ball pivot/centre.
167   */
168  public Instance getPivot() {
169    return m_Pivot;
170  }
171 
172  /**
173   * Sets the radius of the node's
174   * ball.
175   * @param radius The radius of the nodes ball.
176   */
177  public void setRadius(double radius) {
178    m_Radius = radius;
179  }
180 
181  /**
182   * Returns the radius of the node's ball.
183   * @return Radius of node's ball.
184   */
185  public double getRadius() {
186    return m_Radius;
187  }
188 
189  /**
190   * Returns the number of instances in the
191   * hyper-spherical region of this node.
192   * @return The number of instances in the
193   * node.
194   */
195  public int numInstances() {
196    return (m_End-m_Start+1);
197  }
198 
199  /**
200   * Calculates the centroid pivot of a node. The node is given
201   * in the form of an indices array that contains the
202   * indices of the points inside the node.   
203   * @param instList The indices array pointing to the
204   * instances in the node.
205   * @param insts The actual instances. The instList
206   * points to instances in this object. 
207   * @return The calculated centre/pivot of the node. 
208   */
209  public static Instance calcCentroidPivot(int[] instList, Instances insts) {
210    double[] attrVals = new double[insts.numAttributes()];
211   
212    Instance temp;
213    for(int i=0; i<instList.length; i++) {
214      temp = insts.instance(instList[i]);
215      for(int j=0; j<temp.numValues(); j++) {
216        attrVals[j] += temp.valueSparse(j);
217      }
218    }
219    for(int j=0, numInsts=instList.length; j<attrVals.length; j++) {
220      attrVals[j] /= numInsts;
221    }
222    temp = new DenseInstance(1.0, attrVals);
223    return temp;
224  }
225 
226  /**
227   * Calculates the centroid pivot of a node. The node is given
228   * in the form of the portion of an indices array that
229   * contains the indices of the points inside the node.
230   * @param start The start index marking the start of
231   * the portion belonging to the node.
232   * @param end The end index marking the end of the
233   * portion in the indices array that belongs to the node.   
234   * @param instList The indices array pointing to the
235   * instances in the node.
236   * @param insts The actual instances. The instList
237   * points to instances in this object. 
238   * @return The calculated centre/pivot of the node. 
239   */
240  public static Instance calcCentroidPivot(int start, int end, int[] instList, 
241                                          Instances insts) {
242    double[] attrVals = new double[insts.numAttributes()];
243    Instance temp;
244    for(int i=start; i<=end; i++) {
245      temp = insts.instance(instList[i]);
246      for(int j=0; j<temp.numValues(); j++) {
247        attrVals[j] += temp.valueSparse(j);
248      }
249    }
250    for(int j=0, numInsts=end-start+1; j<attrVals.length; j++) {
251      attrVals[j] /= numInsts;
252    }
253   
254    temp = new DenseInstance(1.0, attrVals);   
255    return temp;
256  }
257 
258  /**
259   * Calculates the radius of node.
260   * 
261   * @param instList The indices array containing the indices of the
262   * instances inside the node.
263   * @param insts The actual instances object. instList points to
264   * instances in this object.
265   * @param pivot The centre/pivot of the node.
266   * @param distanceFunction The distance fuction to use to calculate
267   * the radius.
268   * @return The radius of the node.
269   * @throws Exception If there is some problem in calculating the
270   * radius.
271   */
272  public static double calcRadius(int[] instList, Instances insts,Instance pivot, 
273                                 DistanceFunction distanceFunction) 
274                                                  throws Exception {
275    return calcRadius(0, instList.length-1, instList, insts, 
276                      pivot, distanceFunction);
277  }
278 
279  /**
280   * Calculates the radius of a node.
281   *
282   * @param start The start index of the portion in indices array
283   * that belongs to the node.
284   * @param end The end index of the portion in indices array
285   * that belongs to the node.
286   * @param instList The indices array holding indices of
287   * instances.
288   * @param insts The actual instances. instList points to
289   * instances in this object.
290   * @param pivot The centre/pivot of the node.
291   * @param distanceFunction The distance function to use to
292   * calculate the radius.
293   * @return The radius of the node.
294   * @throws Exception If there is some problem calculating the
295   * radius.
296   */
297  public static double calcRadius(int start, int end, int[] instList, 
298                                 Instances insts, Instance pivot, 
299                                 DistanceFunction distanceFunction) 
300                                                             throws Exception {
301    double radius = Double.NEGATIVE_INFINITY;
302   
303    for(int i=start; i<=end; i++) {
304      double dist = distanceFunction.distance(pivot, 
305                                              insts.instance(instList[i]), Double.POSITIVE_INFINITY);
306     
307      if(dist>radius)
308        radius = dist;
309    }
310    return Math.sqrt(radius);
311  }
312 
313  /**
314   * Calculates the centroid pivot of a node based on its
315   * two child nodes (if merging two nodes).
316   * @param child1 The first child of the node.
317   * @param child2 The second child of the node.
318   * @param insts The set of instances on which
319   * the tree is (or is to be) built.
320   * @return The centre/pivot of the node.
321   * @throws Exception If there is some problem calculating
322   * the pivot.
323   */
324  public static Instance calcPivot(BallNode child1, BallNode child2, 
325                                         Instances insts)  throws Exception {
326    Instance p1 = child1.getPivot(), p2 = child2.getPivot();
327    double[] attrVals = new double[p1.numAttributes()];
328   
329    for(int j=0; j<attrVals.length; j++) {
330      attrVals[j] += p1.value(j);
331      attrVals[j] += p2.value(j);
332      attrVals[j] /= 2D;
333    }
334   
335    p1 = new DenseInstance(1.0, attrVals);
336    return p1;
337  }
338
339  /**
340   * Calculates the radius of a node based on its two
341   * child nodes (if merging two nodes).
342   * @param child1 The first child of the node.
343   * @param child2 The second child of the node.
344   * @param pivot The centre/pivot of the node.
345   * @param distanceFunction The distance function to
346   * use to calculate the radius
347   * @return The radius of the node.
348   * @throws Exception If there is some problem
349   * in calculating the radius.
350   */
351  public static double calcRadius(BallNode child1, BallNode child2, 
352                                  Instance pivot, 
353                                  DistanceFunction distanceFunction) 
354                                                             throws Exception {
355    Instance p1 = child1.getPivot(), p2 = child2.getPivot();                                                               
356   
357    double radius = child1.getRadius() + distanceFunction.distance(p1, p2) + 
358                    child2.getRadius();
359   
360    return radius/2;
361  }
362 
363  /**
364   * Returns the revision string.
365   *
366   * @return            the revision
367   */
368  public String getRevision() {
369    return RevisionUtils.extract("$Revision: 5987 $");
370  }
371}
Note: See TracBrowser for help on using the repository browser.