Esempio n. 1
0
// 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;
}
Esempio n. 2
0
// 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;
}
Esempio n. 3
0
// 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;
}
Esempio n. 4
0
// 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);
  }
}