Пример #1
0
        public static TreeNode <Point2d> MakeBfsTree(Point2d rootPt, Func <Point2d, bool> isInDomain)
        {
            TreeNode <Point2d> root = new TreeNode <Point2d>(rootPt);

            PointSet2d alreadyIncluded = new PointSet2d();

            alreadyIncluded.Add(root.value);

            Point2d[] neighbors = new Point2d[8];

            Queue <TreeNode <Point2d> > searchSpace = new Queue <TreeNode <Point2d> >();

            searchSpace.Enqueue(root);

            while (searchSpace.Count > 0)
            {
                var node = searchSpace.Dequeue();

                SetNeighbors(node.value, ref neighbors);
                for (int idx = 0; idx < neighbors.Length; idx++)
                {
                    Point2d pt = neighbors[idx];
                    if (isInDomain(pt) && !alreadyIncluded.Contains(pt))
                    {
                        searchSpace.Enqueue(new TreeNode <Point2d>(pt, node));
                        alreadyIncluded.Add(pt);
                    }
                }
            }

            return(root);
        }
Пример #2
0
        public static TreeNode <Point2d> MakeTreeFromContiguousSet(this PointSet2d pointSet, Func <Point2d, bool> isRoot)
        {
            Point2d?rootPt = null;

            foreach (var pt in pointSet)
            {
                if (isRoot(pt))
                {
                    rootPt = pt;
                }
            }

            if (!rootPt.HasValue)
            {
                return(null);
            }
            else
            {
                return(Utils.MakeBfsTree(rootPt.Value, pt => pointSet.Contains(pt)));
            }
        }
Пример #3
0
        public static Point2d?Bfs(Point2d start, Func <Point2d, bool> isInDomain, Func <Point2d, bool> isSatisfactory)
        {
            PointSet2d alreadyIncluded = new PointSet2d();

            alreadyIncluded.Add(start);

            Point2d[] neighbors = new Point2d[8];

            Queue <Point2d> searchSpace = new Queue <Point2d>();

            searchSpace.Enqueue(start);

            while (searchSpace.Count > 0)
            {
                var current = searchSpace.Dequeue();

                SetNeighbors(current, ref neighbors);
                for (int idx = 0; idx < neighbors.Length; idx++)
                {
                    Point2d pt = neighbors[idx];
                    if (isInDomain(pt) && !alreadyIncluded.Contains(pt))
                    {
                        if (isSatisfactory(pt))
                        {
                            return(pt);
                        }
                        else
                        {
                            searchSpace.Enqueue(pt);
                            alreadyIncluded.Add(pt);
                        }
                    }
                }
            }

            return(null);
        }
Пример #4
0
        public static Dictionary <T, HashSet <PointSet2d> > FindContiguousSets <T>(this IField2d <T> field)
        {
            Dictionary <T, HashSet <PointSet2d> > categoryToSets = new Dictionary <T, HashSet <PointSet2d> >();

            // At the beginning, all points are unaffiliated.
            PointSet2d unaffiliated = new PointSet2d();

            for (int x = 0, y = 0; y < field.Height; y += ++x / field.Width, x %= field.Width)
            {
                unaffiliated.Add(new Point2d(x, y));
            }

            Point2d[] neighbors = new Point2d[8];

            for (int x = 0, y = 0; y < field.Height; y += ++x / field.Width, x %= field.Width)
            {
                Point2d p = new Point2d(x, y);
                if (unaffiliated.Contains(p))
                {
                    // Start a new contiguous set.
                    PointSet2d contiguousSet = new PointSet2d();

                    T key = field[p.y, p.x];

                    // Only points which (1) are unaffiliated and (2) have not been considered
                    // for this set are allowed to be candidates.
                    Queue <Point2d> candidates = new Queue <Point2d>();
                    PointSet2d      considered = new PointSet2d();

                    candidates.Enqueue(p);
                    considered.Add(p);

                    while (candidates.Count > 0)
                    {
                        p = candidates.Dequeue();

                        if (Object.Equals(field[p.y, p.x], key))
                        {
                            unaffiliated.Remove(p);
                            contiguousSet.Add(p);

                            Utils.SetNeighbors(p, ref neighbors);
                            for (int idx = 0; idx < neighbors.Length; idx++)
                            {
                                p = neighbors[idx];
                                if (unaffiliated.Contains(p) && !considered.Contains(p))
                                {
                                    candidates.Enqueue(p);
                                    considered.Add(p);
                                }
                            }
                        }
                    }

                    HashSet <PointSet2d> sets;
                    if (!categoryToSets.TryGetValue(key, out sets))
                    {
                        sets = new HashSet <PointSet2d>();
                        categoryToSets.Add(key, sets);
                    }
                    sets.Add(contiguousSet);
                }
            }

            return(categoryToSets);
        }