// 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; }
int operator() (PuzzleState &left, PuzzleState &right) { // This is an inefficient implementation, but it has // the desired functionality, doesn't require breaking the API // of the PuzzleState class, and is easy to code. ostringstream left_stream; ostringstream right_stream; left.print(left_stream); right.print(right_stream); return left_stream.str().compare(right_stream.str()); }
// 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; }