private static void LoadAndSearch(string pathPrefix)
        {
            Stopwatch clock;
            var       world = new SmallWorld <float[], float>(CosineDistance.NonOptimized);

            Console.Write("Loading HNSW graph... ");
            clock = Stopwatch.StartNew();
            BinaryFormatter formatter     = new BinaryFormatter();
            var             sampleVectors = (List <float[]>)formatter.Deserialize(new MemoryStream(File.ReadAllBytes($"{pathPrefix}.{VectorsPathSuffix}")));

            world.DeserializeGraph(sampleVectors, File.ReadAllBytes($"{pathPrefix}.{GraphPathSuffix}"));
            Console.WriteLine($"Done in {clock.ElapsedMilliseconds} ms.");

            Console.Write($"Generating {TestSize} test vectos... ");
            clock = Stopwatch.StartNew();
            var vectors = RandomVectors(Dimensionality, TestSize);

            Console.WriteLine($"Done in {clock.ElapsedMilliseconds} ms.");

            Console.WriteLine("Running search agains the graph... ");
            using (var listener = new MetricsEventListener(EventSources.GraphSearchEventSource.Instance))
            {
                clock = Stopwatch.StartNew();
                Parallel.ForEach(vectors, (vector) =>
                {
                    world.KNNSearch(vector, 10);
                });
                Console.WriteLine($"Done in {clock.ElapsedMilliseconds} ms.");
            }
        }
    /// <summary>
    /// Entry point to get estimated closest cluster position. Computed from N_CLOSEST_FOR_CLUSTER by default
    /// </summary>
    /// <param name="from"></param>
    /// <returns></returns>
    public Vector3 GetClosestApproximatedClusterPosition(Vector3 from, int k = N_CLOSEST_FOR_CLUSTER)
    {
        // Can't query if not built yet
        if (_graph == null)
        {
            return(from);
        }

        float[] queryPos = { from.x, from.y, from.z };

        IList <SmallWorld <float[], float> .KNNSearchResult> k_closest;

        lock ( _lock ) {
            k_closest = _graph.KNNSearch(queryPos, k);
        }

        // Averaging results positions
        Vector3 avg = Vector3.zero;

        for (int i = 0; i < k_closest.Count; i++)
        {
            avg += new Vector3(k_closest[i].Item[0], k_closest[i].Item[1], k_closest[i].Item[2]);
        }

        return(avg / k_closest.Count);
    }
Пример #3
0
        public void KNNSearchTestAlgorithm4(bool expandBestSelection, bool keepPrunedConnections)
        {
            var parameters = new SmallWorld <float[], float> .Parameters()
            {
                NeighbourHeuristic = NeighbourSelectionHeuristic.SelectHeuristic, ExpandBestSelection = expandBestSelection, KeepPrunedConnections = keepPrunedConnections
            };
            var graph = new SmallWorld <float[], float>(CosineDistance.NonOptimized, DefaultRandomGenerator.Instance, parameters);

            graph.AddItems(vectors);

            int   bestWrong = 0;
            float maxError  = float.MinValue;

            for (int i = 0; i < vectors.Count; ++i)
            {
                var result = graph.KNNSearch(vectors[i], 20);
                var best   = result.OrderBy(r => r.Distance).First();
                Assert.AreEqual(20, result.Count);
                if (best.Id != i)
                {
                    bestWrong++;
                }
                maxError = Math.Max(maxError, best.Distance);
            }
            Assert.AreEqual(0, bestWrong);
            Assert.AreEqual(0, maxError, FloatError);
        }
Пример #4
0
        public void KNNSearchTest()
        {
            var parameters = new SmallWorld <float[], float> .Parameters();

            var graph = new SmallWorld <float[], float>(CosineDistance.NonOptimized, DefaultRandomGenerator.Instance, parameters);

            graph.AddItems(vectors);

            int   bestWrong = 0;
            float maxError  = float.MinValue;

            for (int i = 0; i < vectors.Count; ++i)
            {
                var result = graph.KNNSearch(vectors[i], 20);
                var best   = result.OrderBy(r => r.Distance).First();
                Assert.AreEqual(20, result.Count);
                if (best.Id != i)
                {
                    bestWrong++;
                }
                maxError = Math.Max(maxError, best.Distance);
            }
            Assert.AreEqual(0, bestWrong);
            Assert.AreEqual(0, maxError, FloatError);
        }
Пример #5
0
        public void KNNSearchTest()
        {
            var parameters = new SmallWorld <float[], float> .Parameters();

            var graph = new SmallWorld <float[], float>(CosineDistance.NonOptimized);

            graph.BuildGraph(this.vectors, new Random(42), parameters);

            for (int i = 0; i < this.vectors.Count; ++i)
            {
                var result = graph.KNNSearch(this.vectors[i], 20);
                var best   = result.OrderBy(r => r.Distance).First();
                Assert.AreEqual(20, result.Count);
                Assert.AreEqual(i, best.Id);
                Assert.AreEqual(0, best.Distance, FloatError);
            }
        }
Пример #6
0
        static void Main(string[] args)
        {
            var parameters = new SmallWorld <float[], float> .Parameters()
            {
                M           = 50,
                LevelLambda = 1 / Math.Log(15),
            };

            var       r          = new Random();
            const int dimensions = 100;
            var       vectors    = GetFloatVectors(dimensions, r);
            var       graph      = new SmallWorld <float[], float>(CosineDistance.SIMD);
            var       stopWatch  = new Stopwatch();

            stopWatch.Start();
            graph.BuildGraph(vectors, new Random(42), parameters);
            stopWatch.Stop();
            var buildTime = stopWatch.Elapsed;

            Console.WriteLine($"graph build for {vectors.Count} items in {buildTime}");
            byte[] buffer = graph.SerializeGraph();
            Console.WriteLine($"graph serialized in {buffer.Length} bytes");
            float[] query = GetRandomVector(dimensions, r);

            for (var i = 0; i < 100; i++)
            {
                stopWatch = new Stopwatch();
                stopWatch.Start();
                var best20 = graph.KNNSearch(query, 20);
                stopWatch.Stop();
                buildTime = stopWatch.Elapsed;
                Console.WriteLine($"Top 20 items retrieved in {buildTime}");
            }

            /*foreach (var item in best20)
             * {
             *  Console.WriteLine($"{item.Id} -> {item.Distance}");
             * }*/
        }