Esempio n. 1
0
        /// <summary>
        /// Returns the record in remaininglist with the largest affinity for
        /// one group over the other.
        /// </summary>
        /// <param name="remainingList"></param>
        /// <param name="groupOne"></param>
        /// <param name="groupTwo"></param>
        /// <param name="D1"></param>
        /// <param name="D2"></param>
        /// <returns></returns>
        private static IndexRecord <T> pickNext(List <IndexRecord <T> > remainingList,
                                                NodeRecord <T> groupOne, NodeRecord <T> groupTwo,
                                                out int D1, out int D2)
        {
            IndexRecord <T> nextRecord = null;
            int             maxDiff    = int.MinValue;

            D1 = 0;
            D2 = 0;

            int diff, d1, d2;

            foreach (var record in remainingList)
            {
                // PN1.
                d1 = RTree <T> .EnclosingArea(groupOne.BBox, record.BBox) - groupOne.BBox.GetArea();

                d2 = RTree <T> .EnclosingArea(groupTwo.BBox, record.BBox) - groupTwo.BBox.GetArea();

                diff = Math.Abs(d2 - d1);
                if (diff > maxDiff)
                {
                    maxDiff = diff;
                    // PN2.
                    D1         = d1;
                    D2         = d2;
                    nextRecord = record;
                }
            }

            return(nextRecord);
        }
Esempio n. 2
0
        /// <summary>
        /// Returns the two index records in the remaininglist that, if put into a node,
        /// would have the largest bouding box of any two records.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        private void pickSeeds(List <IndexRecord <T> > remainingList, out IndexRecord <T> a, out IndexRecord <T> b)
        {
            int maxD = int.MinValue;

            a = null;
            b = null;

            foreach (var childNodeA in remainingList)
            {
                foreach (var childNodeB in remainingList)
                {
                    if (childNodeA == childNodeB)
                    {
                        continue;
                    }
                    int D = RTree <T> .EnclosingArea(childNodeA.BBox, childNodeB.BBox);

                    // PS1.
                    // This is a measure inefficiency of grouping items together.
                    D = D - childNodeA.BBox.GetArea() - childNodeB.BBox.GetArea();
                    if (D > maxD)
                    {
                        // PS2.
                        maxD = D;
                        a    = childNodeA;
                        b    = childNodeB;
                    }
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Splits this node into two based on the chosen algorithm.
        /// Returns a new node with some of the records. This node
        /// retains some of the records as well.
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public NodeRecord <T> Split(IndexRecord <T> item)
        {
            NodeRecord <T> newNode = Node.SplitQuadradic(item);

            ResizeBBox();

            // newNode's bounding box should be the right size already.
            return(newNode);
        }
Esempio n. 4
0
        /// <summary>
        /// Attempts to insert a record.
        /// If this succeeds, it resizes the bouding box.
        /// Otherwise return false.
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool TryInsert(IndexRecord <T> item)
        {
            bool success = Node.TryInsert(item);

            if (success)
            {
                ResizeBBox();
            }
            return(success);
        }
Esempio n. 5
0
 /// <summary>
 /// Attempts to insert an item into this's list of records.
 /// If it fails, returns false (the node needs to split).
 /// </summary>
 /// <param name="item"></param>
 /// <returns></returns>
 public bool TryInsert(IndexRecord <T> item)
 {
     if (records.Count < M)
     {
         records.Add(item);
         // Bounding box resizing must be handled by calling function.
         return(true);
     }
     else
     {
         // Need to split.
         return(false);
     }
 }
Esempio n. 6
0
        /// <summary>
        /// Utilizes the Quadradic split algorithm to determine where each
        /// of the records go - either to group one or group two.
        /// </summary>
        /// <param name="newItem"></param>
        /// <returns></returns>
        public NodeRecord <T> SplitQuadradic(IndexRecord <T> newItem)
        {
            List <IndexRecord <T> > itemsToBeAssigned = records;

            itemsToBeAssigned.Add(newItem);

            IndexRecord <T> A, B;

            // QS1.
            pickSeeds(itemsToBeAssigned, out A, out B);
            itemsToBeAssigned.Remove(A);
            itemsToBeAssigned.Remove(B);

            NodeRecord <T> groupOne = new NodeRecord <T>()
            {
                BBox = A.BBox, Node = new RTreeNode <T>(isLeaf)
            };
            NodeRecord <T> groupTwo = new NodeRecord <T>()
            {
                BBox = B.BBox, Node = new RTreeNode <T>(isLeaf)
            };

            groupOne.Node.TryInsert(A);
            groupTwo.Node.TryInsert(B);

            // QS2.
            while (itemsToBeAssigned.Count > 0)
            {
                // QS3.
                int d1, d2;
                var next = pickNext(itemsToBeAssigned, groupOne, groupTwo, out d1, out d2);
                if (d1 < d2)
                {
                    groupOne.TryInsert(next);
                }
                else if (d2 < d1)
                {
                    groupTwo.TryInsert(next);
                }
                else
                {
                    // Insert to whichever is smaller.
                    if (groupOne.Node.GetRecordCount() < groupTwo.Node.GetRecordCount())
                    {
                        groupOne.TryInsert(next);
                    }
                    else
                    {
                        groupTwo.TryInsert(next);
                    }
                }

                itemsToBeAssigned.Remove(next);

                // QS2.
                if (groupOne.Node.GetRecordCount() + itemsToBeAssigned.Count <= m)
                {
                    while (itemsToBeAssigned.Count > 0)
                    {
                        groupOne.TryInsert(itemsToBeAssigned.First());
                        itemsToBeAssigned.Remove(itemsToBeAssigned.First());
                    }
                }

                // QS2.
                if (groupTwo.Node.GetRecordCount() + itemsToBeAssigned.Count <= m)
                {
                    while (itemsToBeAssigned.Count > 0)
                    {
                        groupTwo.TryInsert(itemsToBeAssigned.First());
                        itemsToBeAssigned.Remove(itemsToBeAssigned.First());
                    }
                }
            }

            // Set this equal to group two.
            records = groupTwo.Node.records;
            return(groupOne);
        }