private void BuildTree(List<Point> records, Orthotope bounds, int branchFactor) { int dimensions = records[0].Dimensions; int height = ApproxTreeHeight(records.Count, branchFactor); //Assign partitions to each dimension. int[] dimensionPartitions = GetPartitionPerDimension( GetPartitionPowerFactor(dimensions, height), branchFactor); //Get cell width for each dimension double[] cellWidths = GetPartitionWidth(bounds, dimensionPartitions); //Make Leaves List<Node> leaves = MakeLeaves(bounds, dimensionPartitions, cellWidths); //Build the tree bottom up from leaves. List<Node> nodes = leaves; while (true) { if (nodes.Count == 1) { root = nodes[0]; break; } List<Node> newNodes = new List<Node>(); for (int i = 0; i < (int)(nodes.Count / branchFactor); i++) { IntNode node = new IntNode( nodes.GetRange(i * branchFactor, branchFactor)); newNodes.Add(node); } nodes = newNodes; } }
public PruningRegion(Orthotope o, PrefSpec[] prefs) { if (o == null || prefs == null) throw new ArgumentNullException(); pivot = MakePivot(o, prefs); pref = new PrefSpec[pivot.Dimensions]; Array.Copy(prefs, pref, prefs.Length); }
/// <summary> /// Find the dominant corner (pivot) of the orthotope and make a /// new instance of Point. /// </summary> /// <param name="o"></param> /// <param name="pref"></param> /// <returns></returns> public static Point MakePivot(Orthotope o, PrefSpec[] pref) { Point p = new Point(o.Dimensions); for (int i = 0; i < o.Dimensions; i++) { if (pref[i] == PrefSpec.Min) p[i] = o.Min[i]; else p[i] = o.Max[i]; } return p; }
private List<Node> MakeLeaves(Orthotope dataBound, int[] dimenPartCount, double[] dimenPartWidth) { int dimensions = dimenPartCount.Length; //tracker tracks the current cell to be created. //It's a counter for each dimension, but starts with 0. int[] tracker = new int[dimensions]; List<Node> cells = new List<Node>(); while (true) { //Create a cell. Point min = new Point(dimensions); Point max = new Point(dimensions); for (int d = 0; d < dimensions; d++) { min[d] = dataBound.Min[d] + dimenPartWidth[d] * tracker[d]; max[d] = dataBound.Min[d] + dimenPartWidth[d] * (tracker[d] + 1); } cells.Add(new LeafNode(new Orthotope(min, max))); //Increase the counter to the next cell. if (!IncrementCellTracker(tracker, dimenPartCount)) break; } return cells; }
/// <summary> /// Load data points and their minimal bounding rectangle (MBR). /// </summary> /// <param name="path">The path of the input file.</param> /// <returns>The first element contains the MBR of the data points /// and the second is the list of data points.</returns> private Object[] LoadDataPoints(string path) { List<Point> points = new List<Point>(); Orthotope bound = null; //Load data points from file. using (StreamReader fileReader = new StreamReader(path)) { for (string line = fileReader.ReadLine(); line != null; line = fileReader.ReadLine()) { line = line.Trim(); //Create a new point string[] coordStr = line.Split(new char[] {' ', '\t'}); Point point = new Point(coordStr.Length); for (int i = 0; i < coordStr.Length; i++) { point[i] = double.Parse(coordStr[i]); } //Add point to the list points.Add(point); //Add point to the bound if (bound == null) bound = new Orthotope(point, point); else bound.Add(point); } Object[] result = { bound, points }; return result; } }
private double[] GetPartitionWidth(Orthotope dataBound, int[] dimenPartCount) { //Calculate width of each partition for each dimension double[] widths = new double[dataBound.Dimensions]; for (int i = 0; i < dataBound.Dimensions; i++) { widths[i] = dataBound.Width(i) / dimenPartCount[i]; } return widths; }
/// <summary> /// Determine if this pruning region covers (dominates) an /// orthotope. /// </summary> /// <param name="o">An orthotope</param> /// <param name="pref">An array of preference specifier for /// each dimension.</param> /// <returns>true if the orthotope is completely inside this /// pruning region; false otherwise.</returns> public bool Covers(Orthotope o) { //Find the dominant corner of the orthotope Point p = MakePivot(o, pref); //Check if the dominant point is covered by this pruning region return Covers(p); }
/// <summary> /// Determine whether this rectangle intersects the passed rectangle. /// </summary> /// <param name="o">The rectangle that might intersect this rectangle</param> /// <returns>true if the rectangles intersect, false if they do /// not intersect</returns> public bool Intersects(Orthotope o) { // Every dimension must intersect. If any dimension // does not intersect, return false immediately. for (int i = 0; i < Dimensions; i++) { if (max[i] < o.min[i] || min[i] > o.max[i]) { return false; } } return true; }
/// <summary> /// Computes the union of this orthotope and the passed orthotope, /// storing the result in this orthotope. /// </summary> /// <param name="o">Orthotope to add to this one</param> /// <remarks>The passed orthotope should have the same number /// of dimensions.</remarks> public void Add(Orthotope o) { for (int i = 0; i < Dimensions; i++) { if (o.min[i] < min[i]) { min[i] = o.min[i]; } if (o.max[i] > max[i]) { max[i] = o.max[i]; } } }
/// <summary> /// Return the distance between this rectangle and the passed /// rectangle. If the rectangles overlap, the distance is zero. /// </summary> /// <param name="o">Rectangle to find the distance to</param> /// <returns>Distance between this rectangle and the passed /// rectangle</returns> /// <remarks>The passed rectangle should have the same dimension /// as this orthotope or exception will be thrown.</remarks> public double Distance(Orthotope o) { double distanceSquared = 0; for (int i = 0; i < Dimensions; i++) { double greatestMin = Math.Max(min[i], o.min[i]); double leastMax = Math.Min(max[i], o.max[i]); if (greatestMin > leastMax) { distanceSquared += ((greatestMin - leastMax) * (greatestMin - leastMax)); } } return Math.Sqrt(distanceSquared); }
/// <summary> /// Calculate the volume by which this orthotope would be enlarged /// if added to the passed orthotope. Neither orthotope is altered. /// </summary> /// <param name="o"></param> /// <returns></returns> public double Enlargement(Orthotope o) { throw new NotImplementedException(); }
/// <summary> /// Determine whether this rectangle contains the passed rectangle /// </summary> /// <param name="o">The rectangle that might be contained by this /// rectangle</param> /// <returns>true if this rectangle contains the passed /// rectangle, false if it does not</returns> public bool Contains(Orthotope o) { for (int i = 0; i < Dimensions; i++) { if (max[i] < o.max[i] || min[i] > o.min[i]) { return false; } } return true; }
public IndexEntry(Orthotope mbr, int offset) { this.mbr = mbr.Copy(); this.offset = offset; }
public override bool Insert(Point point) { if (!bounds.Contains(point)) return false; if (mbr == null) mbr = new Orthotope(point, point); else mbr.Add(point); points.Add(point); return true; }
public LeafNode(Orthotope bounds) { if (bounds == null) throw new ArgumentNullException(); this.bounds = bounds.Copy(); this.height = 0; points = new List<Point>(); }
public static long GetSizeInBytes(Orthotope ortho) { return 2 * GetSizeInBytes(ortho.Min); }