/// <summary> /// implimantion of the BFS algorithm /// </summary> /// <remarks>1. insert to queue the start state and insert start state to m_visited /// 2. while queue is not empty /// 2.1 dequeue state and mark as v /// 2.1 if v is the goal /// 2.1.1 get solution /// 2.2 else /// 2.2.1 if v is not in m_visited /// 2.2.1.1 insert v to m_visited /// 2.2.1.2 insert to queue all neigbors of v</remarks> /// <param name="search"></param> /// <returns></returns> public Solution Solve(ISearchable search) { StartTiming(); m_visited.Clear(); m_numofnodes = 1; queue.Enqueue(search.getInitialState()); m_visited.Add(search.getInitialState().ToString(), search.getInitialState()); Solution sol = new Solution(); Astate goal = search.getGoalState(); while (queue.Count != 0) { Astate vertex = queue.Dequeue(); if (vertex.Equals(goal)) { sol = backtrack(vertex); break; } List <Astate> list = search.getAllPossibleStates(vertex); foreach (Astate state in list) { if (!m_visited.ContainsKey((state as MazeState).currentp.ToString())) { m_visited.Add((state as MazeState).currentp.ToString(), state); queue.Enqueue(state); m_numofnodes++; state.cameFrom = vertex; } } } StopTiming(); return(sol); }
/// <summary> /// implimantion of the DFS algorithm /// </summary> /// <remarks>1. insert the start state to the stack. /// 2. While stack not empty /// 2.1 pop from stack and insert to v /// 2.2 if v is the goal /// 2.2.1 get solution /// 2.3 if v is not in the visited list: /// 2.3.1 insert v to m_visited /// 2.3.2 for all neighbors of v, push neighbor to stack</remarks> /// <param name="search"></param> /// <returns></returns> public Solution Solve(ISearchable search) { StartTiming(); m_visited.Clear(); m_numofnodes = 1; stack.Push(search.getInitialState()); Solution sol = new Solution(); Astate goal = search.getGoalState(); while (stack.Count != 0) { Astate vertex = stack.Pop(); if (vertex.Equals(goal)) { sol = backtrack(vertex); break; } if (!m_visited.ContainsKey((vertex as MazeState).currentp.ToString())) { m_visited.Add((vertex as MazeState).currentp.ToString(), vertex); } List <Astate> lolist = search.getAllPossibleStates(vertex); foreach (Astate a in lolist) { if (!m_visited.ContainsKey((a as MazeState).currentp.ToString())) { a.cameFrom = vertex; stack.Push(a); m_numofnodes++; } } } StopTiming(); return(sol); }
/// <summary> /// in order to find the solution we need to go backwards from the goal position to the start position /// </summary> /// <param name="v"></param> /// <returns></returns> private Solution backtrack(Astate v) { Solution sol = new Solution(); MazeState parent = (MazeState)v; while (parent != null) { sol.addState(parent); parent = (MazeState)parent.cameFrom; } sol.Reverse(); return(sol); }
/// <summary> /// get all possible states that can be reached from given state /// </summary> /// <remarks>in a given state s look to all directions - up, down, left, right, floor up, floor down and insert to a list /// all possible directions</remarks> /// <param name="s">Get state for which we need to seek for legible neighbors</param> /// <returns>returns a list with all the directions that we can go through</returns> public List <Astate> getAllPossibleStates(Astate s) { List <MazeState> list = new List <MazeState>(); List <Astate> list2 = new List <Astate>(); Position p = (s as MazeState).currentp; Maze2d maze2 = maze.maze3d[p.z]; try{ if (maze2.maze2d[p.x, p.y + 1] == 0 || maze2.maze2d[p.x, p.y + 1] == 4 || maze2.maze2d[p.x, p.y + 1] == 3) { list.Add(new MazeState(s, new Position(p.x, p.y + 1, p.z))); } } catch (IndexOutOfRangeException e) { }; try{ if (maze2.maze2d[p.x - 1, p.y] == 0 || maze2.maze2d[p.x - 1, p.y] == 3 || maze2.maze2d[p.x - 1, p.y] == 4) { list.Add(new MazeState(s, new Position(p.x - 1, p.y, p.z))); } } catch (Exception e) { }; try{ if (maze2.maze2d[p.x, p.y - 1] == 0 || maze2.maze2d[p.x, p.y - 1] == 3 || maze2.maze2d[p.x, p.y - 1] == 4) { list.Add(new MazeState(s, new Position(p.x, p.y - 1, p.z))); } } catch (Exception e) { }; try{ if (maze2.maze2d[p.x + 1, p.y] == 0 || maze2.maze2d[p.x + 1, p.y] == 3 || maze2.maze2d[p.x + 1, p.y] == 4) { list.Add(new MazeState(s, new Position(p.x + 1, p.y, p.z))); } } catch (Exception e) { }; if (p.z + 1 < (maze as Maze3d).maze3d.Length && ((maze as Maze3d).maze3d[p.z + 1].maze2d[p.x, p.y] == 0 || (maze as Maze3d).maze3d[p.z + 1].maze2d[p.x, p.y] == 4 || (maze as Maze3d).maze3d[p.z + 1].maze2d[p.x, p.y] == 3)) { list.Add(new MazeState(s, new Position(p.x, p.y, p.z + 1))); } if (p.z - 1 >= 0 && p.z - 1 < (maze as Maze3d).maze3d.Length && (((maze as Maze3d).maze3d[p.z - 1].maze2d[p.x, p.y] == 0) || ((maze as Maze3d).maze3d[p.z - 1].maze2d[p.x, p.y] == 3) || ((maze as Maze3d).maze3d[p.z - 1].maze2d[p.x, p.y] == 4))) { list.Add(new MazeState(s, new Position(p.x, p.y, p.z - 1))); } foreach (MazeState m in list) { list2.Add((m as Astate)); } return(list2); }
/// <summary> /// add a state to the solution /// </summary> /// <param name="state"></param> public void addState(Astate state) { m_solu.Add(state); }
/// <summary> /// overrides the equals method /// </summary> /// <param name="state"></param> /// <returns></returns> public override bool Equals(Astate state) { return(currentp.ToString().Equals((state as MazeState).currentp.ToString())); }
/// <summary> /// each maze state is composed from a "father" state and a position /// </summary> /// <param name="camefrom"></param> /// <param name="curr"></param> public MazeState(Astate camefrom, Position curr) : base(camefrom) { state = curr.ToString(); currentp = curr; }
/// <summary> /// override Object's Equals method /// </summary> /// <param name="state"></param> /// <returns></returns> public abstract bool Equals(Astate state);
/// <summary> /// constructor /// </summary> /// <param name="CameFrom"></param> public Astate(Astate CameFrom) { this.cameFrom = cameFrom; }