//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); }
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); }
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); } }
/// <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); }
// 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); }
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>()); }