/// <summary> /// Missing mapping to P objects /// KdTree could be refactored to use P object instead of Math.Net /// /// O(k * log n) /// </summary> /// <param name="s"></param> /// <param name="origin"></param> /// <param name="k"></param> /// <param name="conf"></param> /// <returns></returns> public long UpdateKnn(IAlgorithm s, IP origin, KnnConfiguration conf) { if (conf == null) conf = new KnnConfiguration(); if (conf.SameTypeOnly) throw new NotImplementedException(); if (conf.MaxDistance.HasValue) throw new NotImplementedException(); var sw = new Stopwatch(); sw.Start(); var vector = new DenseVector(new[] { origin.X, origin.Y }); var nn = Tree.FindNearestNNeighbors(vector, conf.K).ToList(); s.Knn.Clear(); s.Knn.Origin = origin; s.Knn.K = conf.K; foreach (var i in nn) { var p = new P { X = i[0], Y = i[1] }; var dist = origin.Distance(p.X,p.Y); s.Knn.NNs.Add(new PDist {Point = p, Distance = dist}); } sw.Stop(); return sw.ElapsedMilliseconds; }
/// <summary> /// O(n * k * logk) // much faster than O(n logn) for k << n /// </summary> /// <param name="s"></param> /// <param name="p"></param> /// <param name="conf"></param> /// <returns></returns> public long UpdateKnn(IAlgorithm s, IP p, KnnConfiguration conf) { conf = conf ?? new KnnConfiguration(); var sw = new Stopwatch(); sw.Start(); s.Knn.Clear(); s.Knn.Origin = p; s.Knn.K = conf.K; //var all = new List<IPDist>(); // naive version var sortedList2 = new SortedList2(); // better naive version var n = s.Points.Count; for (var i = 0; i < n; i++) { var p1 = s.Points[i]; if (p.Equals(p1)) { continue; // don't include origin } if (conf.SameTypeOnly && p.Type != p1.Type) { continue; // only same type used } var dist = p.Distance(p1.X, p1.Y); if (dist >= conf.MaxDistance) { continue; } var pdist = new PDist { Point = p1, Distance = dist }; //all.Add(pdist); // naive version sortedList2.Add(pdist, conf.K); // better naive version } //s.Knn.NNs = all.OrderBy(i => i.Distance).Take(conf.K).ToList(); // O(n logn) s.Knn.NNs = sortedList2.GetAll(); // O(n * k * logk) // better naive version sw.Stop(); return(sw.ElapsedMilliseconds); }
/// <summary> /// Missing mapping to P objects /// KdTree could be refactored to use P object instead of Math.Net /// /// O(k * log n) /// </summary> /// <param name="s"></param> /// <param name="origin"></param> /// <param name="k"></param> /// <param name="conf"></param> /// <returns></returns> public long UpdateKnn(IAlgorithm s, IP origin, KnnConfiguration conf) { if (conf == null) { conf = new KnnConfiguration(); } if (conf.SameTypeOnly) { throw new NotImplementedException(); } if (conf.MaxDistance.HasValue) { throw new NotImplementedException(); } var sw = new Stopwatch(); sw.Start(); var vector = new DenseVector(new[] { origin.X, origin.Y }); var nn = Tree.FindNearestNNeighbors(vector, conf.K).ToList(); s.Knn.Clear(); s.Knn.Origin = origin; s.Knn.K = conf.K; foreach (var i in nn) { var p = new P { X = i[0], Y = i[1] }; var dist = origin.Distance(p.X, p.Y); s.Knn.NNs.Add(new PDist { Point = p, Distance = dist }); } sw.Stop(); return(sw.ElapsedMilliseconds); }
/// <summary> /// O(n * k * logk) // much faster than O(n logn) for k << n /// </summary> /// <param name="s"></param> /// <param name="p"></param> /// <param name="conf"></param> /// <returns></returns> public override long UpdateKnn(IAlgorithm s, IP p, KnnConfiguration conf) { if (conf == null) conf = new KnnConfiguration(); var sw = new Stopwatch(); sw.Start(); s.Knn.Clear(); s.Knn.Origin = p; s.Knn.K = conf.K; //var all = new List<IPDist>(); var sortedList2 = new SortedList2(); var n = s.Points.Count; for (var i = 0; i < n; i++) { var p1 = s.Points[i]; if (p.Equals(p1)) continue; // don't include origin if (conf.SameTypeOnly && p.Type != p1.Type) continue; // only same type used var dist = p.Distance(p1.X, p1.Y); if (dist >= conf.MaxDistance) continue; var pdist = new PDist { Point = p1, Distance = dist }; //all.Add(pdist); sortedList2.Add(pdist, conf.K); } //s.Knn.NNs = all.OrderBy(i => i.Distance).Take(conf.K).ToList(); // O(n logn) s.Knn.NNs = sortedList2.GetAll(); // O(n * k * logk) sw.Stop(); return sw.ElapsedMilliseconds; }