// This function does the actual solving. void solvePuzzle(PuzzleState *start, BagOfPuzzleStates &active, PredDict &seen, vector<PuzzleState*> &solution) { PuzzleState *state; PuzzleState *temp; active.put_in(start); // Must explore the successors of the start state. seen.add(start,NULL); // We've seen this state. It has no predecessor. int foo=0; while (!active.is_empty()) { // Loop Invariants: // 'seen' contains the set of puzzle states that we know how to reach. // 'active' contains the set of puzzle states that we know how to reach, // and whose successors we might not have explored yet. foo++; if (foo % 1000 == 0) cout << foo << endl; state = active.take_out(); // Note: Do not delete this, as this PuzzleState is also in 'seen' // The following two lines are handy for debugging, or seeing what // the algorithm is doing. // 221 STUDENTS: Comment these out when you want the program to // run at full speed! //cout << "Exploring State: \n"; //state->print(cout); //usleep(100000); // Pause for some microseconds, to let human read output if (state->isSolution()) { // Found a solution! cout << "Found solution! \n"; state->print(cout); // Follow predecessors to construct path to solution. temp = state; while (temp!=NULL) { solution.push_back(temp); // Guaranteed to succeed, because these states must have been // added to dictionary already. seen.find(temp,temp); } return; } vector<PuzzleState*> nextMoves = state->getSuccessors(); for (unsigned int i=0; i < nextMoves.size(); i++) { if (!seen.find(nextMoves[i], temp)) { // Never seen this state before. Add it to 'seen' and 'active' active.put_in(nextMoves[i]); seen.add(nextMoves[i], state); } else { delete nextMoves[i]; } } } // Ran out of states to explore. No solution! solution.clear(); return; }
// This function does the actual solving. void solvePuzzle(PuzzleState *start, TodoList<PuzzleState*> &active, PredDict<PuzzleState*> &seen, vector<PuzzleState*> &solution) { PuzzleState *state; PuzzleState *temp; active.add(start); // Must explore the successors of the start state. seen.add(start,NULL); // We've seen this state. It has no predecessor. while (!active.is_empty()) { // Loop Invariants: // 'seen' contains the set of puzzle states that we know how to reach. // 'active' contains the set of puzzle states that we know how to reach, // and whose successors we might not have explored yet. state = active.remove(); // Note: Do not delete this, as this PuzzleState is also in 'seen' // uncomment the next two lines for debugging, if you'd like! // cout << "Exploring State: \n"; // state->print(cout); // cin.get(); if (state->isSolution()) { // Found a solution! cout << "Found solution! \n"; state->print(cout); // Follow predecessors to construct path to solution. temp = state; while (temp!=NULL) { solution.push_back(temp); // Guaranteed to succeed, because these states must have been // added to dictionary already. seen.find(temp,temp); } return; } vector<PuzzleState*> nextMoves = state->getSuccessors(); for (unsigned int i=0; i < nextMoves.size(); i++) { if (!seen.find(nextMoves[i], temp)) { // Never seen this state before. Add it to 'seen' and 'active' active.add(nextMoves[i]); seen.add(nextMoves[i], state); } else { // We're not using this duplicate state; // so, we should delete it. delete nextMoves[i]; } } } // Ran out of states to explore. No solution! cout << "No solution!" << endl; solution.clear(); return; }
// This function does the actual solving. void solveMaze(MazeState *start, BagOfMazeStates &active, PredDict &seen) { MazeState *state; MazeState *temp; active.add(start); // Must explore the successors of the start state. seen.add(start,NULL); // We've seen this state. It has no predecessor. while (!active.is_empty()) { // Loop Invariants: // 'seen' contains the set of maze states that we know how to reach. // 'active' contains the set of maze states that we know how to reach, // and from which there may be new states we haven't explored yet. state = active.remove(); // Note: Don't delete state when done, as this MazeState is also in seen // The following two lines are handy for debugging, or seeing what // the algorithm is doing. // 221 STUDENTS: Comment these out when you want the program to // run at full speed! //cout << "Exploring State: \n"; //state->print(cout); //usleep(20000); // Pause for some microseconds, to let human read output if (state->isSolution()) { // Found a solution! cout << "***** Found a solution!!!!! ***** \n"; int temp; // Throwaway variable to call recursive printTraceTo printTraceTo(state, seen, temp); return; } vector<MazeState*> nextMoves = state->getSuccessors(); for (unsigned int i=0; i < nextMoves.size(); i++) { if (!seen.find(nextMoves[i], temp)) { // Never seen this state before. Add it to 'seen' and 'active' active.add(nextMoves[i]); seen.add(nextMoves[i], state); } else { delete nextMoves[i]; } } } // Ran out of states to explore. No solution! cout << "***** No Solution Exists!!! *****\n"; return; }
// Simple recursive function to print out a sequence of states from // the start state to goal. // length returns how many steps there were in the path to goal. void printTraceTo(MazeState *goal, PredDict &seen, int &length) { // Should not be called with NULL if (goal==NULL) { cerr << "Error: Do not call printSolution without a goal.\n"; return; } // Find the state that we used to get to goal. MazeState *predecessor; seen.find(goal,predecessor); if (predecessor==NULL) { // Base Case: If predecessor is NULL, then goal is the starting state. length = 0; cout << "Starting from this state:\n"; goal->print(cout); } else { // Recursive Case: Print solution to predecessor, then one step to goal. printTraceTo(predecessor, seen, length); length++; cout << "Step " << length << " leads to...\n"; goal->print(cout); } }