コード例 #1
0
        //public static HashSet<PM_Vec2> ReachableCells_Set(
        //    this PM_Maze maze,
        //    PM_Vec2 cell,
        //    HashSet<PM_Vec2> visitedCells
        //    )
        //{
        //    if (visitedCells == null || visitedCells.Count == 0)
        //    {
        //        visitedCells = new HashSet<PM_Vec2>() { cell };
        //    }

        //    HashSet<PM_Vec2> neighbors = maze.Cell_ActiveNeighbors_Set(cell);
        //    foreach (var neighbor in neighbors)
        //    {
        //        if (visitedCells.Contains(neighbor) == false)
        //        {
        //            visitedCells.Add(neighbor);
        //            maze.ReachableCells_Set(neighbor, visitedCells);
        //        }
        //    }

        //    return visitedCells;
        //}

        public static List <Vec2i> ReachableCells_List(
            this PM_Maze maze,
            Vec2i cell,
            List <Vec2i> visitedCells
            )
        {
            if (visitedCells == null || visitedCells.Count == 0)
            {
                visitedCells = new List <Vec2i>()
                {
                    cell
                };
            }

            List <Vec2i> neighbors = maze.Cells_Connected_To_Cell__List(cell);

            foreach (var neighbor in neighbors)
            {
                if (visitedCells.Contains(neighbor) == false)
                {
                    visitedCells.Add(neighbor);
                    maze.ReachableCells_List(neighbor, visitedCells);
                }
            }

            return(visitedCells);
        }
コード例 #2
0
        public static int Num_Steps_NecessaryToReachAllCells(
            this PM_Maze maze,
            Vec2i root
            )
        {
            var allNodes = maze.CellsPositions_All_List();

            Dictionary <Vec2i, Vec2i> predecessors = new Dictionary <Vec2i, Vec2i>();
            Dictionary <Vec2i, int>   depths       = new Dictionary <Vec2i, int>();

            depths.Add(root, 0);

            foreach (var node in allNodes)
            {
                predecessors.Add(node, node);
            }

            HashSet <Vec2i> visited_Nodes = new HashSet <Vec2i>()
            {
                root
            };

            Queue <Vec2i> searchQueue = new Queue <Vec2i>();

            searchQueue.Enqueue(root);

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

                var          neighbors          = maze.Cells_Connected_To_Cell__List(current);
                List <Vec2i> unvisitedNeighbors = neighbors.FindAll(x => visited_Nodes.Contains(x) == false);

                foreach (var neighbor in unvisitedNeighbors)
                {
                    predecessors[neighbor] = current;
                    searchQueue.Enqueue(neighbor);
                    visited_Nodes.Add(neighbor);
                    depths.Add(neighbor, depths[current] + 1);
                }
            }

            int maxDepth = 0;

            foreach (var node in allNodes)
            {
                if (depths[node] > maxDepth)
                {
                    maxDepth = depths[node];
                }
            }

            return(maxDepth);
        }
コード例 #3
0
        public static HashSet <Vec2i> BFS_ReachableCells_Set(
            this PM_Maze maze,
            Vec2i root,
            bool includeRoot
            )
        {
            var allNodes = maze.CellsPositions_All_List();

            Dictionary <Vec2i, Vec2i> predecessors = new Dictionary <Vec2i, Vec2i>();

            foreach (var node in allNodes)
            {
                predecessors.Add(node, node);
            }

            HashSet <Vec2i> visited_Nodes = new HashSet <Vec2i>()
            {
                root
            };

            Queue <Vec2i> searchQueue = new Queue <Vec2i>();

            searchQueue.Enqueue(root);

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

                var          neighbors          = maze.Cells_Connected_To_Cell__List(current);
                List <Vec2i> unvisitedNeighbors = neighbors.FindAll(x => visited_Nodes.Contains(x) == false);

                foreach (var neighbor in unvisitedNeighbors)
                {
                    predecessors[neighbor] = current;
                    searchQueue.Enqueue(neighbor);
                    visited_Nodes.Add(neighbor);
                }
            }

            if (includeRoot)
            {
                return(visited_Nodes);
            }
            else
            {
                visited_Nodes.Remove(root);
                return(visited_Nodes);
            }
        }
コード例 #4
0
        /// <summary>
        /// Method that searches whether the destination cell is reachable from the root cell.
        /// It searches the graph using a BFS algorithm.
        /// </summary>
        /// <param name="maze"></param>
        /// <param name="root"></param>
        /// <param name="destination"></param>
        /// <returns></returns>
        public static bool Q_Is_Reachable_BFS(this PM_Maze maze, Vec2i root, Vec2i destination)
        {
            if (root.Equals(destination))
            {
                return(true);
            }

            List <Vec2i> all_nodes = maze.CellsPositions_All_List();

            Dictionary <Vec2i, bool> visited_nodes = new Dictionary <Vec2i, bool>();

            foreach (var n in all_nodes)
            {
                visited_nodes.Add(n, false);
            }

            Queue <Vec2i> searchQueue = new Queue <Vec2i>();

            searchQueue.Enqueue(root);
            visited_nodes[root] = true;

            while (searchQueue.Count > 0)
            {
                var          current            = searchQueue.Dequeue();
                var          neighbors          = maze.Cells_Connected_To_Cell__List(current);
                List <Vec2i> unvisitedNeighbors = neighbors.FindAll(x => visited_nodes[x] == false);

                foreach (var neighbor in unvisitedNeighbors)
                {
                    searchQueue.Enqueue(neighbor);
                    visited_nodes[neighbor] = true;

                    if (neighbor.Equals(destination))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
コード例 #5
0
        // A recursive function that uses visited[]
        // and parent to detect cycle in subgraph
        // reachable from vertex v.
        private static bool IsCyclic_Helper(
            PM_Maze maze,
            Vec2i node,
            HashSet <Vec2i> visitedNodes,
            Vec2i parent
            )
        {
            // Mark the current node as visited
            visitedNodes.Add(node);

            var nodeNeighbors = maze.Cells_Connected_To_Cell__List(node);

            // Recur for all the vertices
            // adjacent to this vertex
            foreach (var neighbor in nodeNeighbors)
            {
                // If an adjacent is not visited,
                // then recur for that adjacent
                if (visitedNodes.Contains(neighbor) == false)
                {
                    if (IsCyclic_Helper(maze, neighbor, visitedNodes, node))
                    {
                        return(true);
                    }
                }

                // If an adjacent is visited and
                // not parent of current vertex,
                // then there is a cycle.
                else if (neighbor != parent)
                {
                    return(true);
                }
            }
            return(false);
        }
コード例 #6
0
        public static List <Vec2i> BFS_ShortestPath(
            this PM_Maze maze,
            Vec2i root,
            Vec2i destination
            )
        {
            if (root.Equals(destination))
            {
                throw new System.ArgumentException("root equals destination");
            }

            Dictionary <Vec2i, Vec2i> predecessors = new Dictionary <Vec2i, Vec2i>();

            var allCells = maze.CellsPositions_All_List();

            foreach (var node in allCells)
            {
                predecessors.Add(node, node);
            }

            List <Vec2i> visitedNodes = new List <Vec2i>();

            Queue <Vec2i> searchQueue = new Queue <Vec2i>();

            searchQueue.Enqueue(root);
            visitedNodes.Add(root);
            bool foundDestination = false;

            while (searchQueue.Count > 0 && foundDestination == false)
            {
                var          current            = searchQueue.Dequeue();
                var          neighbors          = maze.Cells_Connected_To_Cell__List(current);
                List <Vec2i> unvisitedNeighbors = neighbors.FindAll(x => visitedNodes.Contains(x) == false);

                foreach (var neighbor in unvisitedNeighbors)
                {
                    predecessors[neighbor] = current;
                    searchQueue.Enqueue(neighbor);
                    visitedNodes.Add(neighbor);

                    if (neighbor.Equals(destination))
                    {
                        foundDestination = true;
                        break;
                    }
                }
            }

            List <Vec2i> shortestPath = new List <Vec2i>();

            bool pathFinished        = false;
            var  currentPathPosition = destination;

            shortestPath.Add(currentPathPosition);
            while (pathFinished == false)
            {
                var predecessor = predecessors[currentPathPosition];
                if (predecessor.Equals(currentPathPosition) == false)
                {
                    shortestPath.Add(predecessor);
                    currentPathPosition = predecessor;
                }
                else
                {
                    pathFinished = true;
                }
            }

            shortestPath.Reverse();

            if (
                shortestPath.Contains(root)
                &&
                shortestPath.Contains(destination)
                )
            {
                return(shortestPath);
            }

            return(new List <Vec2i>());
        }