예제 #1
0
        /***************************************************/
        /**** Public Methods                            ****/
        /***************************************************/

        public static List <LocalData <T> > CloseToPoint <T>(this PointMatrix <T> matrix, Point refPt, double maxDist)
        {
            // Collect all the points within cells in range
            Vector range = new Vector {
                X = maxDist, Y = maxDist, Z = maxDist
            };
            List <LocalData <T> > inCells = matrix.SubMatrixData <T>(Create.DiscretePoint(refPt - range, matrix.CellSize), Create.DiscretePoint(refPt + range, matrix.CellSize));

            // Keep only points within maxDist distance of refPt
            double maxSqrDist            = maxDist * maxDist;
            List <LocalData <T> > result = new List <LocalData <T> >();

            foreach (LocalData <T> tuple in inCells)
            {
                if (tuple.Position.PMSquareDistance(refPt) < maxSqrDist)
                {
                    result.Add(tuple);
                }
            }

            // Return final result
            return(result);
        }
예제 #2
0
        /***************************************************/
        /**** Public Methods                            ****/
        /***************************************************/

        public static List <List <T> > ClusterDBSCAN <T>(this List <T> items, Func <T, T, bool> metricFunction, int minCount = 1)
        {
            DBSCANObject <T>[] DBSCANItems = items.Select(x => Create.DBSCANObject <T>(x)).ToArray();
            int c = 0;

            for (int i = 0; i < DBSCANItems.Length; i++)
            {
                DBSCANObject <T> p = DBSCANItems[i];
                if (p.IsVisited)
                {
                    continue;
                }
                p.IsVisited = true;

                DBSCANObject <T>[] neighbourItems = null;
                RegionQuery(DBSCANItems, p.ClusterItem, metricFunction, out neighbourItems);

                if (neighbourItems.Length < minCount)
                {
                    p.ClusterId = -1;
                }
                else
                {
                    c++;
                    ExpandCluster(DBSCANItems, p, neighbourItems, metricFunction, c, minCount);
                }
            }

            List <List <T> > clusters = new List <List <T> >(
                DBSCANItems
                .Where(x => x.ClusterId > 0)
                .GroupBy(x => x.ClusterId)
                .Select(x => x.Select(y => y.ClusterItem).ToList())
                );

            return(clusters);
        }