Exemplo n.º 1
0
 public void DoProcess(SortedLimitedList<Double> mustBeEqualTo, SortedLimitedList<Double> expectedOutput)
 {
     // TODO: make "mustBeEqualTo" list equal to "expectedOutput".
     // 0. Processor will be created once and then will be used billion times.
     // 1. Use methods: AddFirst, AddLast, AddBefore, AddAfter, Remove to modify list.
     // 2. Do not change expectedOutput list.
     // 3. At any time number of elements in list could not exceed the "Limit".
     // 4. "Limit" will be passed into Processor's constructor. All "mustBeEqualTo" and "expectedOutput" lists will have the same "Limit" value.
     // 5. At any time list elements must be in non-descending order.
     // 6. Implementation must perform minimal possible number of actions (AddFirst, AddLast, AddBefore, AddAfter, Remove).
     // 7. Implementation must be fast and do not allocate excess memory.
 }
Exemplo n.º 2
0
    // Limited Best-Bin-First k-d-tree nearest neighbour search.
    //
    // (Using the algorithm described in the paper "Shape indexing using
    // approximate nearest-neighbour search in high-dimensional spaces",
    // available at http://www.cs.ubc.ca/spider/lowe/papers/cvpr97-abs.html)
    //
    // Find the approximate nearest neighbour to the hyperspace point 'target'
    // within the kd-tree using 'searchSteps' tail recursions at most (each
    // recursion deciding about one neighbours' fitness).
    //
    // After return 'resDist' contains the absolute distance of the
    // approximate nearest neighbour from the target point. The approximate
    // nearest neighbour is returned.
    public ArrayList NearestNeighbourListBBF(IKDTreeDomain target, int q, int searchSteps)
    {
        HyperRectangle hr = HyperRectangle.CreateUniverseRectangle(target.DimensionCount);

        SortedLimitedList best     = new SortedLimitedList(q);
        SortedLimitedList searchHr = new SortedLimitedList(searchSteps);

        float         dummyDist;
        IKDTreeDomain nearest = NearestNeighbourListBBFI(best, q, target, hr, float.MaxValue, out dummyDist, searchHr, ref searchSteps);

        foreach (BestEntry be in best)
        {
            be.Distance = Math.Sqrt(be.DistanceSq);
        }

        return(best);
    }
Exemplo n.º 3
0
    public ArrayList NearestNeighbourList(IKDTreeDomain target, out double resDist, int q)
    {
        HyperRectangle hr =
            HyperRectangle.CreateUniverseRectangle(target.DimensionCount);

        SortedLimitedList best = new SortedLimitedList(q);

        IKDTreeDomain nearest = NearestNeighbourListI(best, q, target, hr,
                                                      Double.PositiveInfinity, out resDist);

        resDist = Math.Sqrt(resDist);

        foreach (BestEntry be in best)
        {
            be.Distance = Math.Sqrt(be.Distance);
        }

        return(best);
    }
Exemplo n.º 4
0
    private IKDTreeDomain NearestNeighbourListBBFI(SortedLimitedList best,
                                                   int q, IKDTreeDomain target, HyperRectangle hr, int maxDistSq,
                                                   out int resDistSq, SortedLimitedList searchHr, ref int searchSteps)
    {
        resDistSq = Int32.MaxValue;

        IKDTreeDomain pivot = dr;

        best.Add(new BestEntry(dr, KDTree.DistanceSq(target, dr), true));

        HyperRectangle leftHr  = hr;
        HyperRectangle rightHr = leftHr.SplitAt(splitDim,
                                                pivot.GetDimensionElement(splitDim));

        HyperRectangle nearerHr, furtherHr;
        KDTree         nearerKd, furtherKd;

        if (target.GetDimensionElement(splitDim) <=
            pivot.GetDimensionElement(splitDim))
        {
            nearerKd  = left;
            nearerHr  = leftHr;
            furtherKd = right;
            furtherHr = rightHr;
        }
        else
        {
            nearerKd  = right;
            nearerHr  = rightHr;
            furtherKd = left;
            furtherHr = leftHr;
        }

        IKDTreeDomain nearest = null;
        int           distSq;

        searchHr.Add(new HREntry(furtherHr, furtherKd, pivot,
                                 furtherHr.Distance(target)));

        if (nearerKd == null)
        {
            distSq = Int32.MaxValue;
        }
        else
        {
            nearest = nearerKd.NearestNeighbourListBBFI(best, q, target, nearerHr,
                                                        maxDistSq, out distSq, searchHr, ref searchSteps);
        }

        if (best.Count >= q)
        {
            maxDistSq = ((BestEntry)best[q - 1]).DistanceSq;
        }
        else
        {
            maxDistSq = Int32.MaxValue;
        }

        if (searchHr.Count > 0)
        {
            HREntry hre = (HREntry)searchHr[0];
            searchHr.RemoveAt(0);

            furtherHr = hre.HR;
            furtherKd = hre.Tree;
            pivot     = hre.Pivot;
        }

        searchSteps -= 1;
        if (searchSteps > 0 &&
            furtherHr.IsInReach(target, Math.Sqrt(maxDistSq)))
        {
            int ptDistSq = KDTree.DistanceSq(pivot, target);
            if (ptDistSq < distSq)
            {
                nearest = pivot;
                distSq  = ptDistSq;

                maxDistSq = distSq;
            }

            int           tempDistSq;
            IKDTreeDomain tempNearest = null;
            if (furtherKd == null)
            {
                tempDistSq = Int32.MaxValue;
            }
            else
            {
                tempNearest = furtherKd.NearestNeighbourListBBFI(best, q,
                                                                 target, furtherHr, maxDistSq, out tempDistSq, searchHr,
                                                                 ref searchSteps);
            }

            if (tempDistSq < distSq)
            {
                nearest = tempNearest;
                distSq  = tempDistSq;
            }
        }

        resDistSq = distSq;
        return(nearest);
    }
Exemplo n.º 5
0
    private IKDTreeDomain NearestNeighbourListI(SortedLimitedList best,
                                                int q, IKDTreeDomain target, HyperRectangle hr, double maxDistSq,
                                                out double resDistSq)
    {
        resDistSq = Double.PositiveInfinity;

        IKDTreeDomain pivot = dr;

        best.Add(new BestEntry(dr, KDTree.DistanceSq(target, dr)));

        HyperRectangle leftHr  = hr;
        HyperRectangle rightHr = leftHr.SplitAt(splitDim,
                                                pivot.GetDimensionElement(splitDim));

        HyperRectangle nearerHr, furtherHr;
        KDTree         nearerKd, furtherKd;

        if (target.GetDimensionElement(splitDim) <=
            pivot.GetDimensionElement(splitDim))
        {
            nearerKd  = left;
            nearerHr  = leftHr;
            furtherKd = right;
            furtherHr = rightHr;
        }
        else
        {
            nearerKd  = right;
            nearerHr  = rightHr;
            furtherKd = left;
            furtherHr = leftHr;
        }

        IKDTreeDomain nearest = null;
        double        distSq;

        if (nearerKd == null)
        {
            distSq = Double.PositiveInfinity;
        }
        else
        {
            nearest = nearerKd.NearestNeighbourListI(best, q, target, nearerHr,
                                                     maxDistSq, out distSq);
        }

        if (best.Count >= q)
        {
            maxDistSq = ((BestEntry)best[q - 1]).Distance;
        }
        else
        {
            maxDistSq = Double.PositiveInfinity;
        }

        if (furtherHr.IsInReach(target, Math.Sqrt(maxDistSq)))
        {
            double ptDistSq = KDTree.DistanceSq(pivot, target);
            if (ptDistSq < distSq)
            {
                nearest = pivot;
                distSq  = ptDistSq;

                maxDistSq = distSq;
            }

            double        tempDistSq;
            IKDTreeDomain tempNearest = null;
            if (furtherKd == null)
            {
                tempDistSq = Double.PositiveInfinity;
            }
            else
            {
                tempNearest = furtherKd.NearestNeighbourListI(best, q, target,
                                                              furtherHr, maxDistSq, out tempDistSq);
            }

            if (tempDistSq < distSq)
            {
                nearest = tempNearest;
                distSq  = tempDistSq;
            }
        }

        resDistSq = distSq;
        return(nearest);
    }
Exemplo n.º 6
0
        public void DoProcess(SortedLimitedList<Double> mustBeEqualTo, SortedLimitedList<Double> expectedOutput)
        {
            // TODO: make "mustBeEqualTo" list equal to "expectedOutput".
            // 0. Processor will be created once and then will be used billion times.
            // 1. Use methods: AddFirst, AddLast, AddBefore, AddAfter, Remove to modify list.
            // 2. Do not change expectedOutput list.
            // 3. At any time number of elements in list could not exceed the "Limit".
            // 4. "Limit" will be passed into Processor's constructor. All "mustBeEqualTo" and "expectedOutput" lists will have the same "Limit" value.
            // 5. At any time list elements must be in non-descending order.
            // 6. Implementation must perform minimal possible number of actions (AddFirst, AddLast, AddBefore, AddAfter, Remove).
            // 7. Implementation must be fast and do not allocate excess memory.

            oneEOItem = expectedOutput.Last;
            oneMBETItem = mustBeEqualTo.Last;
            //Delete in mustBeEqualTo all which greater than last from expectedOutput
            while(oneMBETItem!=null){
            if(oneEOItem !=null && oneMBETItem.Value.CompareTo(oneEOItem.Value)>0){
                remMBETItem = oneMBETItem;
                oneMBETItem = oneMBETItem.Previous;
                mustBeEqualTo.Remove(remMBETItem);
            }else if(oneEOItem == null){
                remMBETItem = oneMBETItem;
                oneMBETItem = oneMBETItem.Previous;
                mustBeEqualTo.Remove(remMBETItem);
            } else {
                oneMBETItem = oneMBETItem.Previous;
            }
            }
            //Delete in mustBeEqualTo all which not found in expectedOutput from the beginning
            oneEOItem = expectedOutput.First;
            int totalEOItems=0;
            oneMBETItem = mustBeEqualTo.First;
            while(oneEOItem != null && oneMBETItem!=null){
            twoEOItem = oneEOItem.Next;
            totalEOItems++;
            int kolvoEOItems=1;
            while(twoEOItem!=null && oneEOItem.Value.CompareTo(twoEOItem.Value)==0){
                kolvoEOItems++;
                totalEOItems++;
                twoEOItem=twoEOItem.Next;
            }
            while(oneMBETItem!=null && oneEOItem.Value.CompareTo(oneMBETItem.Value)>=0){
            if(oneEOItem.Value.CompareTo(oneMBETItem.Value)>0){
                remMBETItem = oneMBETItem;
                oneMBETItem = oneMBETItem.Next;
                mustBeEqualTo.Remove(remMBETItem);
            }else{
                twoMBETItem = oneMBETItem.Next;
                int kolvoMBETItems=1;
                while(twoMBETItem!=null && oneMBETItem.Value.CompareTo(twoMBETItem.Value)==0){
                    kolvoMBETItems++;
                    twoMBETItem=twoMBETItem.Next;
                }
                while(kolvoMBETItems>kolvoEOItems){
                    remMBETItem = oneMBETItem;
                    oneMBETItem = oneMBETItem.Next;
                    mustBeEqualTo.Remove(remMBETItem);
                    kolvoMBETItems--;
                }
                oneMBETItem = twoMBETItem;
            }
            }
            oneEOItem = twoEOItem;
            }

            if(totalEOItems>iLimit){
            throw new Exception("Number of elements in 'expectedOutput' exceed the 'Limit'.");
            }
            //Insert in mustBeEqualTo all which found in expectedOutput from the beginning

            oneEOItem = expectedOutput.First;
            oneMBETItem = mustBeEqualTo.First;
            while(oneEOItem != null){
            twoEOItem = oneEOItem.Next;
            int kolvoEOItems=1;
            while(twoEOItem!=null && oneEOItem.Value.CompareTo(twoEOItem.Value)==0){
                kolvoEOItems++;
                twoEOItem=twoEOItem.Next;
             		}

            if(oneMBETItem == null){
                for(int i=0;i<kolvoEOItems;i++){
                    mustBeEqualTo.AddLast(oneEOItem.Value);
                }
                //oneMBETItem = mustBeEqualTo.Last;
            }else if(oneEOItem.Value.CompareTo(oneMBETItem.Value)<0){

                for(int i=0;i<kolvoEOItems;i++){
             				mustBeEqualTo.AddBefore(oneMBETItem,oneEOItem.Value);
                }

            }else if(oneEOItem.Value.CompareTo(oneMBETItem.Value)==0){
                twoMBETItem = oneMBETItem.Next;
                kolvoEOItems--;
                while(twoMBETItem!=null && oneMBETItem.Value.CompareTo(twoMBETItem.Value)==0){
                    kolvoEOItems--;
                    twoMBETItem=twoMBETItem.Next;
                }
                for(int i=0;i<kolvoEOItems;i++){
                    mustBeEqualTo.AddAfter(oneMBETItem,oneEOItem.Value);
                }
                oneMBETItem = twoMBETItem;
            }

            oneEOItem = twoEOItem;
            }
        }
Exemplo n.º 7
0
    private IKDTreeDomain NearestNeighbourListI(SortedLimitedList best, int q, IKDTreeDomain target, HyperRectangle hr, double maxDistSq, out double resDistSq)
    {
        resDistSq = Double.PositiveInfinity;

        IKDTreeDomain pivot = dr;

        best.Add(new BestEntry(dr, KDTree.DistanceSq(target, dr)));

        HyperRectangle leftHr  = hr;
        HyperRectangle rightHr = leftHr.SplitAt(splitDim,
                                                pivot.GetDimensionElement(splitDim));

        HyperRectangle nearerHr, furtherHr;
        KDTree         nearerKd, furtherKd;

        // step 5-7
        if (target.GetDimensionElement(splitDim) <=
            pivot.GetDimensionElement(splitDim))
        {
            nearerKd  = left;
            nearerHr  = leftHr;
            furtherKd = right;
            furtherHr = rightHr;
        }
        else
        {
            nearerKd  = right;
            nearerHr  = rightHr;
            furtherKd = left;
            furtherHr = leftHr;
        }

        // step 8
        IKDTreeDomain nearest = null;
        double        distSq;

        // No child, bottom reached!
        if (nearerKd == null)
        {
            distSq = Double.PositiveInfinity;
        }
        else
        {
            nearest = nearerKd.NearestNeighbourListI(best, q, target, nearerHr,
                                                     maxDistSq, out distSq);
        }

        // step 9
        //maxDistSq = Math.Min (maxDistSq, distSq);
        if (best.Count >= q)
        {
            maxDistSq = ((BestEntry)best[q - 1]).Distance;
        }
        else
        {
            maxDistSq = Double.PositiveInfinity;
        }

        // step 10
        if (furtherHr.IsInReach(target, Math.Sqrt(maxDistSq)))
        {
            double ptDistSq = KDTree.DistanceSq(pivot, target);
            if (ptDistSq < distSq)
            {
                // steps 10.1.1 to 10.1.3
                nearest = pivot;
                distSq  = ptDistSq;

                // TODO: use k-element list

                /*
                 * best.Add (new BestEntry (pivot, ptDistSq));
                 * best.Sort ();
                 */

                maxDistSq = distSq;
            }

            // step 10.2
            double        tempDistSq;
            IKDTreeDomain tempNearest = null;
            if (furtherKd == null)
            {
                tempDistSq = Double.PositiveInfinity;
            }
            else
            {
                tempNearest = furtherKd.NearestNeighbourListI(best, q, target,
                                                              furtherHr, maxDistSq, out tempDistSq);
            }

            // step 10.3
            if (tempDistSq < distSq)
            {
                nearest = tempNearest;
                distSq  = tempDistSq;
            }
        }

        resDistSq = distSq;
        return(nearest);
    }