Ejemplo n.º 1
0
  // find a solution to the initial board (using the A* algorithm)
  public Solver(Board initial) {
    Board twin = initial.twin();
    SearchNode minNode = null;
    boolean isTwinRound = false;
    MinPQ<SearchNode> currentPQ = null;

    minPQ.insert(new SearchNode(initial));
    minPQForTwin.insert(new SearchNode(twin));

    while (true) {
      // Searching solution in the initial board and and its twin board
      // simultaneously(alternating in loops).
      // It has been proven by Math theory that exactly one of the two
      // will lead to the goal board. If a solution is found in the twin
      // board, it immediately proves that the initial board is not solvable,
      // and the search will terminate there.
      // Otherwise, the initial board will reach a solution.
      if (isTwinRound) {
        currentPQ = minPQForTwin;
      } else {
        currentPQ = minPQ;
      }

      minNode = currentPQ.delMin();
      if (minNode.getBoard().isGoal()) {
        break;
      } else {
        for (Board neighbor : minNode.getBoard().neighbors()) {
          // Insert the neighbors into the MinPQ if:
          // 1. Current node contains the initial board(has no prev node)
          // 2. The new neighbor is not the same as current node's previous search node.
          //    This is a critical optimization used to reduce unnecessary
          //    exploration of already visited search nodes.
          if (minNode.getPrev() == null || !neighbor.equals(minNode.getPrev().getBoard())) {
            currentPQ.insert(new SearchNode(neighbor, minNode));
          }
        }
        // Flip the state of the isTwinRound flag
        isTwinRound = isTwinRound ? false : true;
      }
    }

    if (isTwinRound) {
      isSolvable = false;
      solution = null;
    } else {
      isSolvable = true;
      solution = minNode;
      moves = solution.getMoves();
    }
  }