예제 #1
0
        public void MTreeAddTest()
        {
            MTree <IPoint> tree = new MTree <IPoint>(2, 3, (x, y) => GeometryDistanceAlgorithm.Distance(x, y));

            tree.Add(this.geometries[0]);
            tree.NumberOfDataItems.ShouldBe(1);

            tree.Add(this.geometries[1]);
            tree.NumberOfDataItems.ShouldBe(2);

            tree.Add(this.geometries[2]);
            tree.NumberOfDataItems.ShouldBe(3);

            tree.Add(this.geometries[3]);
            tree.NumberOfDataItems.ShouldBe(4);

            for (int i = 4; i < this.geometries.Count; i++)
            {
                tree.Add(this.geometries[i]);
            }

            tree.NumberOfDataItems.ShouldBe(this.geometries.Count);

            tree = new MTree <IPoint>(2, 3, (x, y) => GeometryDistanceAlgorithm.Distance(x, y));

            tree.Add(this.geometries);
            tree.NumberOfDataItems.ShouldBe(this.geometries.Count);

            Should.Throw <ArgumentNullException>(() => tree.Add((IPoint)null));
            Should.Throw <ArgumentNullException>(() => tree.Add((IEnumerable <IPoint>)null));

            // try to insert item already in the tree
            Should.Throw <ArgumentException>(() => tree.Add(this.geometries[0]));
        }
예제 #2
0
 private void PopulateTree <T>(MTree <T> tree, List <T> points)
 {
     foreach (T point in points)
     {
         tree.Add(point);
     }
 }
예제 #3
0
        public void RangeSearchTest()
        {
            int            maxItems      = 10000;
            int            maxNodes      = 25;
            double         distThreshold = 1000;
            Random         rand          = new Random();
            CartesianPoint testPoint     = new CartesianPoint(0, 0);

            MTree <CartesianPoint> tree             = new MTree <CartesianPoint>(CartesianPoint.PythagoreanTheorem, maxNodes);
            List <CartesianPoint>  itemsInThreshold = new List <CartesianPoint>();

            CartesianPoint newPoint;

            for (int i = 0; i < maxItems; i++)
            {
                int xMultiplier = rand.Next(-2, 1);
                while (xMultiplier == 0)
                {
                    xMultiplier = rand.Next(-2, 1);
                }

                int yMultiplier = rand.Next(-2, 1);
                while (yMultiplier == 0)
                {
                    yMultiplier = rand.Next(-2, 1);
                }

                double x = maxItems * xMultiplier * rand.NextDouble() * 0.05;
                double y = maxItems * yMultiplier * rand.NextDouble() * 0.05;

                newPoint = new CartesianPoint(x, y);

                tree.Add(newPoint);

                double dist = tree.GetDistance(newPoint, testPoint);

                if (dist <= distThreshold)
                {
                    itemsInThreshold.Add(newPoint);
                }
            }

            List <CartesianPoint> neighbors = tree.RangeSearch(testPoint, distThreshold);

            Assert.AreEqual(itemsInThreshold.Count, neighbors.Count, "RangeSearch did not return the correct number of elements.");

            foreach (var neighbor in neighbors)
            {
                double dist = tree.GetDistance(neighbor, testPoint);

                Assert.IsTrue(dist <= distThreshold, "RangeSearch returned an item outside of the search radius.");
                Assert.IsTrue(itemsInThreshold.Contains(neighbor), "RangeSearch returned an invalid item");
            }

            foreach (var closeItem in itemsInThreshold)
            {
                Assert.IsTrue(neighbors.Contains(closeItem), "RangeSearch did not return an item within the search radius.");
            }
        }
예제 #4
0
        public void KNearestNeighborsTest()
        {
            int            maxItems  = 10000;
            int            k         = 100;
            Random         rand      = new Random();
            CartesianPoint testPoint = new CartesianPoint(0, 0);

            MTree <CartesianPoint>         tree       = new MTree <CartesianPoint>(CartesianPoint.PythagoreanTheorem);
            PriorityQueue <CartesianPoint> kNeighbors = new PriorityQueue <CartesianPoint>(k);

            CartesianPoint newPoint;

            for (int i = 0; i < maxItems; i++)
            {
                int xMultiplier = rand.Next(-2, 1);
                while (xMultiplier == 0)
                {
                    xMultiplier = rand.Next(-2, 1);
                }

                int yMultiplier = rand.Next(-2, 1);
                while (yMultiplier == 0)
                {
                    yMultiplier = rand.Next(-2, 1);
                }

                double x = maxItems * xMultiplier * rand.NextDouble() * 0.05;
                double y = maxItems * yMultiplier * rand.NextDouble() * 0.05;

                newPoint = new CartesianPoint(x, y);

                tree.Add(newPoint);

                double dist = tree.GetDistance(newPoint, testPoint);

                kNeighbors.Enqueue(newPoint, dist);
            }

            PriorityQueue <CartesianPoint> queryReturns = tree.KNearestNeighborSearch(testPoint, k);

            Assert.AreEqual(k, queryReturns.Count, "K neighor search did not return the correct number of items.");

            while (kNeighbors.HasNext)
            {
                var neighbor = kNeighbors.Dequeue();
                var result   = queryReturns.Dequeue();

                Assert.AreEqual(neighbor.Value, result.Value, "K neighbor search returned wrong item.");
                Assert.AreEqual(neighbor.Key, result.Key, "K neighbor search returned correct item with wrong distance.");
            }

            Assert.IsFalse(queryReturns.HasNext, "K neighbor search returned too many items.");
        }
예제 #5
0
        public void MTreeSearchTest()
        {
            MTree <IPoint> tree = new MTree <IPoint>(2, 3, (x, y) => GeometryDistanceAlgorithm.Distance(x, y));

            tree.Search(this.geometries[0]).ShouldBeEmpty();

            IPoint[] points = new IPoint[9];

            for (Int32 i = 0; i < 9; i++)
            {
                points[i] = this.factory.CreatePoint(i, 0);
                tree.Add(points[i]);
            }

            // search without limits should return all items in the tree
            tree.Search(this.factory.CreatePoint(2, 0)).Count().ShouldBe(9);

            // search returns the correct data items in the correct order with correct distance information
            List <ResultItem <IPoint> > results = new List <ResultItem <IPoint> >(tree.Search(this.factory.CreatePoint(8, 0)));
            List <IPoint> expectedResults       = new List <IPoint>(points.Reverse());

            for (Int32 i = 0; i < points.Length; i++)
            {
                results[i].Item.ShouldBe(expectedResults[i]);
                results[i].Distance.ShouldBe(i);
            }

            // search with a given radius should return only the elements within that radius
            tree.Search(this.factory.CreatePoint(8, 0), 1.0D).Count().ShouldBe(2);
            tree.Search(this.factory.CreatePoint(7, 0), 1.0D).Count().ShouldBe(3);
            tree.Search(this.factory.CreatePoint(9, 0), 1.0D).Count().ShouldBe(1);
            tree.Search(this.factory.CreatePoint(10, 0), 1.0D).Count().ShouldBe(0);

            // search with a given limit should return only that amount of elements
            tree.Search(this.factory.CreatePoint(2, 0), 0).Count().ShouldBe(0);
            tree.Search(this.factory.CreatePoint(2, 0), 1).Count().ShouldBe(1);
            tree.Search(this.factory.CreatePoint(2, 0), 5).Count().ShouldBe(5);
            tree.Search(this.factory.CreatePoint(2, 0), 10).Count().ShouldBe(9);

            // search with both radius and limit where radius contains less elements than limit
            tree.Search(this.factory.CreatePoint(2, 0), 1.1D, 5).Count().ShouldBe(3);

            // search with both radius and limit where radius contains more elements than limit
            tree.Search(this.factory.CreatePoint(2, 0), 1.1D, 2).Count().ShouldBe(2);

            // errors
            Should.Throw <ArgumentNullException>(() => tree.Search(null));
        }
예제 #6
0
        public void ContainsTest()
        {
            int         maxNodeSize = 25;
            int         numItems    = 10000;
            MTree <int> tree        = new MTree <int>((x, y) => Math.Abs(x - y), maxNodeSize);

            for (int i = 0; i < numItems; i++)
            {
                tree.Add(i);
                Assert.AreEqual(i + 1, tree.Count, "Count is not returning the correct value.");
            }

            for (int i = 0; i < numItems; i++)
            {
                Assert.IsTrue(tree.Contains(i), "Contains is returning false for a value that has been inserted in the MTree.");
            }
        }
예제 #7
0
    public static void Function()
    {
        MTree <int> mTree = new MTree <int>();

        mTree.Add(123);
        mTree.Add(324);
        mTree.Add(45);
        mTree.Add(78);
        mTree.Add(126653);
        mTree.Add(144523);
        mTree.Add(1624444443);
        mTree.Add(12 + 73);
        mTree.MidOrder();
        WriteLine("--------------------------------------------------");
        mTree.PreOrder();
        WriteLine("--------------------------------------------------");
        mTree.PostOrder();
        WriteLine("--------------------------------------------------");
        WriteLine(mTree.Max());
    }
예제 #8
0
        public void ItemInsertVerification()
        {
            int    maxItems = 1000;
            int    maxNodes = 25;
            Random rand     = new Random();

            MTree <CartesianPoint> tree = new MTree <CartesianPoint>(CartesianPoint.PythagoreanTheorem, maxNodes);

            CartesianPoint newPoint;

            for (int i = 1; i <= maxItems; i++)
            {
                int xMultiplier = rand.Next(-2, 1);
                while (xMultiplier == 0)
                {
                    xMultiplier = rand.Next(-2, 1);
                }

                int yMultiplier = rand.Next(-2, 1);
                while (yMultiplier == 0)
                {
                    yMultiplier = rand.Next(-2, 1);
                }

                double x = maxItems * xMultiplier * rand.NextDouble() * 0.05;
                double y = maxItems * yMultiplier * rand.NextDouble() * 0.05;

                newPoint = new CartesianPoint(x, y);

                tree.Add(newPoint);

                Assert.AreEqual(i, tree.Count, "MTree does not give correct Count after adding a new element.");
                Assert.IsTrue(tree.Contains(newPoint), "MTree does not say it Contains new item that has been added.");

                NodeDescentAssert(tree.Root, 1, maxNodes);
            }
        }
예제 #9
0
        static void Main(string[] args)
        {
            var mtreeStopwatch     = new Stopwatch();
            var fastMtreeStopWatch = new Stopwatch();

            var originalTimes = new List <long>();
            var fastTimes     = new List <long>();

            var dataSize     = 100000;
            var testDataSize = 50;
            var range        = 1000000;
            var neighbors    = 10;
            var dimensions   = 1000;

            Console.WriteLine($"{nameof(dataSize)}: {dataSize}");
            Console.WriteLine($"{nameof(dimensions)}: {dimensions}");
            Console.WriteLine($"{nameof(neighbors)}: {neighbors}");
            Console.WriteLine();

            var testData = Supercluster.Tests.Utilities.GenerateDoubles(testDataSize, range, dimensions);

            for (int index = 0; index < testData.Length; index++)
            {
                var treeData = Supercluster.Tests.Utilities.GenerateDoubles(dataSize, range, dimensions);
                var target   = testData[index];


                // 1. Build Trees
                var fastMtree = new FastMTree <double[]> {
                    Capacity = 3, Metric = Metrics.L2Norm_Double
                };
                foreach (var point in treeData)
                {
                    fastMtree.Add(point);
                }


                var mtree = new MTree <double[]> {
                    Capacity = 3, Metric = Metrics.L2Norm_Double
                };
                foreach (var point in treeData)
                {
                    mtree.Add(point);
                }

                GC.Collect();
                GCLatencyMode oldMode = GCSettings.LatencyMode;

                // Make sure we can always go to the catch block,
                // so we can set the latency mode back to `oldMode`
                RuntimeHelpers.PrepareConstrainedRegions();

                try
                {
                    GCSettings.LatencyMode = GCLatencyMode.LowLatency;

                    // Measure Trees
                    mtreeStopwatch.Start();
                    var resultsList = mtree.NearestNeighbors(target, neighbors).ToArray();
                    mtreeStopwatch.Stop();

                    fastMtreeStopWatch.Start();
                    var fastResults = fastMtree.NearestNeighbors(target, neighbors).ToArray();
                    fastMtreeStopWatch.Stop();

                    // Generation 2 garbage collection is now
                    // deferred, except in extremely low-memory situations
                }
                finally
                {
                    // ALWAYS set the latency mode back
                    GCSettings.LatencyMode = oldMode;
                }


                // Print times
                if (index != 0) // We skip first run because of jitting
                {
                    // Record Times
                    originalTimes.Add(mtreeStopwatch.ElapsedTicks);
                    fastTimes.Add(fastMtreeStopWatch.ElapsedTicks);
                    Console.WriteLine(mtreeStopwatch.ElapsedTicks + " " + fastMtreeStopWatch.ElapsedTicks);
                }

                // reset stopwatches
                mtreeStopwatch.Reset();
                fastMtreeStopWatch.Reset();
            }

            Console.WriteLine("Average: " + originalTimes.Average() + " " + fastTimes.Average());
            Console.Read();
        }