public static bool IsCyclic( this PM_Maze maze ) { List <Vec2i> nodes = maze.CellsPositions_All_List(); // Mark all the vertices as not visited // and not part of recursion stack HashSet <Vec2i> visitedNodes = new HashSet <Vec2i>(); // Call the recursive helper function // to detect cycle in different DFS trees foreach (var node in nodes) { // Don't recur for u if already visited if (visitedNodes.Contains(node) == false) { if (IsCyclic_Helper(maze, node, visitedNodes, new Vec2i(-1, -1))) { return(true); } } } return(false); }
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); }
public static HashSet <Vec2i> BFS_ReachableNodes_MaximumSteps( this PM_Maze maze, Vec2i root, bool includeRoot, int maximumSteps ) { // start the bfs search... Dictionary <Vec2i, Vec2i> predecessors = new Dictionary <Vec2i, Vec2i>(); Dictionary <Vec2i, int> numSteps = new Dictionary <Vec2i, int>(); var allNodes = maze.CellsPositions_All_List(); //T dummyNode = T.Dummy(); foreach (var node in allNodes) { predecessors.Add(node, node); numSteps.Add(node, int.MaxValue); } HashSet <Vec2i> visited_Nodes = new HashSet <Vec2i>() { root }; Queue <Vec2i> searchQueue = new Queue <Vec2i>(); searchQueue.Enqueue(root); numSteps[root] = 0; while (searchQueue.Count > 0) { var current = searchQueue.Dequeue(); if (numSteps[current] < maximumSteps) { HashSet <Vec2i> unvisitedNeighbors = maze.Cells_Connected_To_Cell__Set(current); unvisitedNeighbors.ExceptWith(visited_Nodes); foreach (var neighbor in unvisitedNeighbors) { predecessors[neighbor] = current; numSteps[neighbor] = numSteps[current] + 1; searchQueue.Enqueue(neighbor); visited_Nodes.Add(neighbor); } } } HashSet <Vec2i> reachable_within_steps = new HashSet <Vec2i>(); foreach (var node in visited_Nodes) { if (numSteps[node] <= maximumSteps) { reachable_within_steps.Add(node); } } if (includeRoot) { return(reachable_within_steps); } else { reachable_within_steps.Remove(root); return(reachable_within_steps); } }
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>()); }