Tiger Goat Grass and Boat man how to pass from West to East in the River using BFS and DFS



Step 1>


package com.kartik.river.pass;
import java.util.ArrayList;
import java.util.Arrays;
/**
 * A state is defined as a 4-bit string (encapsulated by
 * the Pos enum) which represents whether a particular entity (in the order
 * TigerGoatGrassState) is on the west or east side of the river.
 *
 * @author kartik chandra Mandal
 *
 */
public class TigerGoatGrassState implements State
{
 // constant for the goal state
 private final TigerGoatGrassState.Pos[] GOAL = new TigerGoatGrassState.Pos[]
 { Pos.EAST, Pos.EAST, Pos.EAST, Pos.EAST };
 /*
  * All fwgc states are defined by the 4-item array of Pos primitives, either
  * east or west (side of the river) for each member of the problem
  * "BoatMan, Tiger, Goat, Grass" in that order
  */
 public enum Pos
 {
  WEST, EAST
 };
 // The current 4-bit representation of the state
 public Pos[] curState;
 /**
  * Default Constructor
  */
 public TigerGoatGrassState()
 {
  curState = new Pos[]
  { Pos.WEST, Pos.WEST, Pos.WEST, Pos.WEST };
 }
 /**
  * Polymorphic constructor #1
  *
  * @param fPos
  *            - Farmer position
  * @param wPos
  *            - Tiger position
  * @param gPos
  *            - Goat position
  * @param cPos
  *            - Grass position
  */
 public TigerGoatGrassState(Pos fPos, Pos wPos, Pos gPos, Pos cPos)
 {
  curState = new Pos[]
  { fPos, wPos, gPos, cPos };
 }
 /**
  * Polymorphic constructor #2
  *
  * @param stateArr
  *            - Array containing a state, which has all four positions
  */
 public TigerGoatGrassState(TigerGoatGrassState.Pos[] stateArr)
 {
  curState = new Pos[]
  { stateArr[0], stateArr[1], stateArr[2], stateArr[3] };
 }
 /**
  * How much it costs to come to this state
  */
 @Override
 public double findCost()
 {
  return 1;
 }
 /**
  * Generate all possible successors to the current state.
  *
  * Will trim out successor states that match a state description in the
  * "invalid states" array.
  */
 @Override
 public ArrayList<State> genSuccessors()
 {
  ArrayList<State> successors = new ArrayList<State>();
  TigerGoatGrassState.Pos[] tempState = Arrays.copyOf(curState, curState.length);
  /*
   * If the farmer is on the west He can take the w
   */
  // if the farmer is on the west
  if (tempState[0] == Pos.WEST)
  {
   // he must select an entity to take
   // taking the tiger east, if the goat isn't alone there
   if (tempState[1] == Pos.WEST)
   {
    tempState[0] = Pos.EAST;
    tempState[1] = Pos.EAST;
    successors.add(new TigerGoatGrassState(tempState));
    tempState = Arrays.copyOf(curState, curState.length);// reset
   }
   // taking the goat east
   if (tempState[2] == Pos.WEST)
   {
    tempState[0] = Pos.EAST;
    tempState[2] = Pos.EAST;
    successors.add(new TigerGoatGrassState(tempState));
    tempState = Arrays.copyOf(curState, curState.length);
   }
   // taking the grass east, if the goat isn't alone there
   if (tempState[3] == Pos.WEST)
   {
    tempState[0] = Pos.EAST;
    tempState[3] = Pos.EAST;
    successors.add(new TigerGoatGrassState(tempState));
    tempState = Arrays.copyOf(curState, curState.length);
   }
   // going alone, if we didn't add anything
   tempState[0] = Pos.EAST;
   successors.add(new TigerGoatGrassState(tempState));
   tempState = Arrays.copyOf(curState, curState.length);
  }
  // if the farmer is on the east
  else
  {
   // he must select an entity to take
   // taking the tiger west
   if (tempState[1] == Pos.EAST)
   {
    tempState[0] = Pos.WEST;
    tempState[1] = Pos.WEST;
    successors.add(new TigerGoatGrassState(tempState));
    tempState = Arrays.copyOf(curState, curState.length);
   }
   // taking the goat west
   if (tempState[2] == Pos.EAST)
   {
    tempState[0] = Pos.WEST;
    tempState[2] = Pos.WEST;
    successors.add(new TigerGoatGrassState(tempState));
    tempState = Arrays.copyOf(curState, curState.length);
   }
   // taking the grass west
   if (tempState[3] == Pos.EAST)
   {
    tempState[0] = Pos.WEST;
    tempState[3] = Pos.WEST;
    successors.add(new TigerGoatGrassState(tempState));
    tempState = Arrays.copyOf(curState, curState.length);
   }
   // going alone
   tempState[0] = Pos.WEST;
   successors.add(new TigerGoatGrassState(tempState));
   tempState = Arrays.copyOf(curState, curState.length);
  }
  for (int i = 0; i < successors.size(); i++)
  {
   TigerGoatGrassState s = (TigerGoatGrassState) successors.get(i);
   tempState = s.curState;
   // check for conflicts, also don't return to the starting state why
   // not
   if (Arrays.equals(tempState, new TigerGoatGrassState.Pos[]
   { Pos.EAST, Pos.EAST, Pos.WEST, Pos.WEST })
     || Arrays.equals(tempState, new TigerGoatGrassState.Pos[]
     { Pos.EAST, Pos.WEST, Pos.WEST, Pos.WEST })
     || Arrays.equals(tempState, new TigerGoatGrassState.Pos[]
     { Pos.EAST, Pos.WEST, Pos.WEST, Pos.EAST })
     || Arrays.equals(tempState, new TigerGoatGrassState.Pos[]
     { Pos.WEST, Pos.EAST, Pos.EAST, Pos.WEST })
     || Arrays.equals(tempState, new TigerGoatGrassState.Pos[]
     { Pos.WEST, Pos.WEST, Pos.EAST, Pos.EAST })
     || Arrays.equals(tempState, new TigerGoatGrassState.Pos[]
     { Pos.WEST, Pos.EAST, Pos.EAST, Pos.EAST })
     || Arrays.equals(tempState, new TigerGoatGrassState.Pos[]
     { Pos.WEST, Pos.WEST, Pos.WEST, Pos.WEST }))
   {
    successors.remove(i);
    i = 0; // start the search over to ensure all nodes are checked
      // x.x
   }
  }
  return successors;
 }
 /**
  * Check to see if the current state is the goal state.
  *
  * @return - true or false, depending on whether the current state matches
  *         the goal
  */
 @Override
 public boolean isGoal()
 {
  if (Arrays.equals(curState, GOAL))
  {
   return true;
  }
  return false;
 }
 /**
  * Overriden equals method. Generated by Eclipse
  */
 @Override
 public boolean equals(Object obj)
 {
  if (this == obj)
   return true;
  else if (obj == null)
   return false;
  else if (getClass() != obj.getClass())
   return false;
  TigerGoatGrassState other = (TigerGoatGrassState) obj;
  if (!curState.equals(other.curState))
   return false;
  return true;
 }
 /**
  * Method to print out the current state. Prints the current position of
  * each thing.
  */
 @Override
 public void printState()
 {
 
  System.out.println("Boatman: " + curState[0]+"\t|");
  System.out.println("Tiger: " + curState[1]+"\t|");
  System.out.println("Goat: " + curState[2]+"\t|");
  System.out.println("Grass: " + curState[3]+"\t|");
 }

 @Override
 public void printStateOdd() {
  StringBuffer br = new StringBuffer();
  br.append("Boatman: ").append(curState[0]).append("\n\t\t")
    .append("Tiger: ").append(curState[1]).append("\n\t\t")
    .append("Goat: ").append(curState[2]).append("\n\t\t")
    .append("Grass: ").append(curState[3]).append("\n");
  String newTabFromat = br.toString();
  System.out.println(newTabFromat);
 }

 /**
  * Overloaded equals method to compare two states.
  *
  * @return true or false, depending on whether the states are equal
  */
 @Override
 public boolean equals(State s)
 {
  if (Arrays.equals(curState, ((TigerGoatGrassState) s).getCurState()))
  {
   return true;
  }
  else
   return false;
 }
 /**
  * @return the curState
  */
 public Pos[] getCurState()
 {
  return curState;
 }
}




Step 2>
package com.kartik.river.pass;
import java.util.ArrayList;
/**
 *
 * State interface from which problem states inherit. Defines a method to check
 * if the current state is a goal, generate successors, and find the cost to
 * come to the current state.
 *
 * @author kartik chandra Mandal
 *
 */
public interface State {
 /**
  * determine if current state is goal
  *
  * @return boolean
  */
 boolean isGoal();
 /**
  * generate successors to the current state
  *
  * @return ArrayList<State>
  */
 ArrayList<State> genSuccessors();
 /**
  * determine cost from initial state to THIS state
  *
  * @return double
  */
 double findCost();
 /**
  * print the current state
  */
 public void printState();
 /**
  * print the current state
  */
 public void printStateOdd();
 /**
  * compare the actual state data
  *
  * @param s
  *            s
  * @return boolean
  */
 public boolean equals(State s);
}


Step 3>


package com.kartik.river.pass;
/**
 *
 * Class to represent a SearchNode. This will be a wrapper for a State, and
 * track the cost to get to that state and the state's parent node.
 *
 * @author kartik chandra Mandal
 *
 */
public class SearchNode {
 private State curState;
 private SearchNode parent;
 private double cost; // cost to get to this state
 private double hCost; // heuristic cost
 private double fCost; // f(n) cost
 /**
  * Constructor for the root SearchNode
  *
  * @param state
  *            the state passed in
  */
 public SearchNode(State state) {
  curState = state;
  parent = null;
  cost = 0;
  hCost = 0;
  fCost = 0;
 }
 /**
  * Constructor for all other SearchNodes
  *
  * @param prev
  *            the parent node
  * @param state
  *            the state
  * @param currentCost
  *            the g(n) cost to get to this node
  * @param heuristic
  *            the h(n) cost to get to this node
  */
 public SearchNode(SearchNode prev, State state, double currentCost,
   double heuristic) {
  parent = prev;
  curState = state;
  cost = currentCost;
  hCost = heuristic;
  fCost = cost + hCost;
 }
 /**
  * @return the curState
  */
 public State getCurState() {
  return curState;
 }
 /**
  * @return the parent
  */
 public SearchNode getParent() {
  return parent;
 }
 /**
  * @return the cost
  */
 public double getCost() {
  return cost;
 }
 /**
  *
  * @return the heuristic cost
  */
 public double getHCost() {
  return hCost;
 }
 /**
  *
  * @return the f(n) cost for A*
  */
 public double getFCost() {
  return fCost;
 }
}


Step 4>


package com.kartik.river.pass;
import java.util.ArrayList;
import java.util.Stack;
/**
 * Defines a Depth-First search to be performed on a qualifying puzzle.
 * Currently supports TigerGoatGrassState.
 *
 * @author kartik chandra Mandal
 */
public class DFSearchForBTGG {
 /**
  * Initialization function for TigerGoatGrassState DFSearch
  */
 public static void search(boolean d) {
  SearchNode root = new SearchNode(new TigerGoatGrassState());
  Stack<SearchNode> stack = new Stack<SearchNode>();
  stack.add(root);
  performSearch(stack, d);
 }
 /*
  * Helper method to check to see if a SearchNode has already been evaluated.
  * Returns true if it has, false if it hasn't.
  */
 private static boolean checkRepeats(SearchNode searNode) {
  boolean retValue = false;
  SearchNode checkNode = searNode;
  // While n's parent isn't null, check to see if it's equal to the node
  // we're looking for.
  while (searNode.getParent() != null && !retValue) {
   if (searNode.getParent().getCurState()
     .equals(checkNode.getCurState())) {
    retValue = true;
   }
   searNode = searNode.getParent();
  }
  return retValue;
 }
 /**
  * Performs a DFSearch using q as the search space
  *
  * @param stackOfSearchNode
  *            - A SearchNode queue to be populated and searched
  */
 public static void performSearch(Stack<SearchNode> stackOfSearchNode,
   boolean flag) {
  int searchCount = 1; // counter for number of iterations
  while (!stackOfSearchNode.isEmpty()) // while the queue is not empty
  {
   SearchNode tempNode = (SearchNode) stackOfSearchNode.pop();
   // if tempNode is not the goal state
   if (!tempNode.getCurState().isGoal()) {
    // generate tempNode's immediate successors
    ArrayList<State> tempSuccessors = tempNode.getCurState()
      .genSuccessors();
    /*
     * Loop through the successors, wrap them in a SearchNode, check
     * if they've already been evaluated, and if not, add them to
     * the queue
     */
    for (int i = 0; i < tempSuccessors.size(); i++) {
     // second parameter here adds the cost of the new node to
     // the current cost total in the SearchNode
     SearchNode newNode = new SearchNode(tempNode,
       tempSuccessors.get(i), tempNode.getCost()
         + tempSuccessors.get(i).findCost(), 0);
     if (!checkRepeats(newNode)) {
      stackOfSearchNode.add(newNode);
     }
    }
    searchCount++;
   } else
   // The goal state has been found. Print the path it took to get to
   // it.
   {
    // Use a stack to track the path from the starting state to the
    // goal state
    Stack<SearchNode> solutionPath = new Stack<SearchNode>();
    solutionPath.push(tempNode);
    tempNode = tempNode.getParent();
    while (tempNode.getParent() != null) {
     solutionPath.push(tempNode);
     tempNode = tempNode.getParent();
    }
    solutionPath.push(tempNode);
    // The size of the stack before looping through and emptying it.
    int loopSize = solutionPath.size();
    System.out
      .println("How to crossing the river of boat man by DFS algo?");
    System.out.println("From->To\t|    To->From");
    System.out.println("-------------------------------");
    for (int i = 0; i < loopSize; i++) {
     tempNode = solutionPath.pop();
     if (i % 2 == 0) {
      tempNode.getCurState().printState();
     } else {
      System.out.print("\t\t");
      tempNode.getCurState().printStateOdd();
     }
     System.out.println();
     System.out.println();
    }
    System.out.println("The cost was: " + tempNode.getCost());
    if (flag) {
     System.out.println("The number of nodes examined: "
       + searchCount);
    }
    System.exit(0);
   }
  }
  System.out.println("Error! No solution found!");
 }
}


Step 5>


package com.kartik.river.pass;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
/**
 * Defines a Bredth-First search to be performed on a qualifying puzzle.
 * Currently supports TigerGoatGrassState.
 *
 * @author kartik chandra Mandal
 */
public class BFSearchForBTGG {
 /**
  * Initialization function for TigerGoatGrassState BFSearch
  */
 public static void search(boolean d) {
  SearchNode root = new SearchNode(new TigerGoatGrassState());
  Queue<SearchNode> queue = new LinkedList<SearchNode>();
  queue.add(root);
  performSearch(queue, d);
 }
 /**
  * Helper method to check to see if a SearchNode has already been evaluated.
  * Returns true if it has, false if it hasn't.
  */
 private static boolean checkRepeats(SearchNode n) {
  boolean retValue = false;
  SearchNode checkNode = n;
  // While n's parent isn't null, check to see if it's equal to the node
  // we're looking for.
  while (n.getParent() != null && !retValue) {
   if (n.getParent().getCurState().equals(checkNode.getCurState())) {
    retValue = true;
   }
   n = n.getParent();
  }
  return retValue;
 }
 /**
  *
  * Performs a BFSearch using q as the search space
  *
  * @param q
  *            - A SearchNode queue to be populated and searched
  * @param d
  *            A SearchNode queue to be populated and searched
  */
 public static void performSearch(Queue<SearchNode> q, boolean d) {
  int searchCount = 1; // counter for number of iterations
  while (!q.isEmpty()) // while the queue is not empty
  {
   SearchNode tempNode = (SearchNode) q.poll();
   if (!tempNode.getCurState().isGoal()) // if tempNode is not the goal
             // state
   {
    ArrayList<State> tempSuccessors = tempNode.getCurState()
      .genSuccessors(); // generate tempNode's immediate
           // successors
    /*
     * Loop through the successors, wrap them in a SearchNode, check
     * if they've already been evaluated, and if not, add them to
     * the queue
     */
    for (int i = 0; i < tempSuccessors.size(); i++) {
     // second parameter here adds the cost of the new node to
     // the current cost total in the SearchNode
     SearchNode newNode = new SearchNode(tempNode,
       tempSuccessors.get(i), tempNode.getCost()
         + tempSuccessors.get(i).findCost(), 0);
     if (!checkRepeats(newNode)) {
      q.add(newNode);
     }
    }
    searchCount++;
   } else
   // The goal state has been found. Print the path it took to get to
   // it.
   {
    // Use a stack to track the path from the starting state to the
    // goal state
    Stack<SearchNode> solutionPath = new Stack<SearchNode>();
    solutionPath.push(tempNode);
    tempNode = tempNode.getParent();
    while (tempNode.getParent() != null) {
     solutionPath.push(tempNode);
     tempNode = tempNode.getParent();
    }
    solutionPath.push(tempNode);
    // The size of the stack before looping through and emptying it.
    int loopSize = solutionPath.size();
    System.out
      .println("How to crossing the river of boat man by BFS algo?");
    System.out.println("From->To\t|    To->From");
    System.out.println("-------------------------------");
    for (int i = 0; i < loopSize; i++) {
     tempNode = solutionPath.pop();
     if (i % 2 == 0) {
      tempNode.getCurState().printState();
     } else {
      System.out.print("\t\t");
      tempNode.getCurState().printStateOdd();
     }
     System.out.println();
     System.out.println();
    }
    System.out.println("The cost was: " + tempNode.getCost());
    if (d) {
     System.out.println("The number of nodes examined: "
       + searchCount);
    }
    System.exit(0);
   }
  }
  // This should never happen with our current puzzles.
  System.out.println("Error! No solution found!");
 }
}


Step 6>


package com.kartik.river.pass;
import java.util.Scanner;
public class ProblemSolver
{
 static char continueOption;
 static char menuOpion;

 public static void main(String[] args) {
  // Numbers to be adjusted if the debug toggle is present, as components
  // of args will be in different locations if it is.
  // Print out correct usage and end the program if there aren't any
  // parameters
  do {
   System.out
     .println("'B' - To be execute forTiger Goat And Grass problem by Bfs algo running");
   System.out
     .println("'D' - To be execute forTiger Goat And Grass problem by Dfs algo running");
   System.out.println("'N' - To quite running program");
   System.out.println("Please choose your choices");
   Scanner keyboard = new Scanner(System.in);
   String input = keyboard.next();
   menuOpion = input.charAt(0);
   boolean debug = false;
   switch (menuOpion) {
   case 'B':
    BFSearchForBTGG.search(debug);
    break;
   case 'D':
    DFSearchForBTGG.search(debug);
    break;
   default:
    System.out.println("you enter wrong menu option");
   }
   System.out.println();
   System.out.print("Do you want to Continue? Y/N");
   continueOption = keyboard.next().charAt(0);
  } while (continueOption == 'Y' || continueOption == 'y');
 }
}


Out put:
'B' - To be execute forTiger Goat And Grass problem by Bfs algo running
'D' - To be execute forTiger Goat And Grass problem by Dfs algo running
'N' - To quite running program
Please choose your choices
B
How to crossing the river of boat man by BFS algo?
From->To |    To->From
-------------------------------
Boatman: WEST |
Tiger: WEST |
Goat: WEST |
Grass: WEST |

  Boatman: EAST
  Tiger: WEST
  Goat: EAST
  Grass: WEST


Boatman: WEST |
Tiger: WEST |
Goat: EAST |
Grass: WEST |

  Boatman: EAST
  Tiger: EAST
  Goat: EAST
  Grass: WEST


Boatman: WEST |
Tiger: EAST |
Goat: WEST |
Grass: WEST |

  Boatman: EAST
  Tiger: EAST
  Goat: WEST
  Grass: EAST


Boatman: WEST |
Tiger: EAST |
Goat: WEST |
Grass: EAST |

  Boatman: EAST
  Tiger: EAST
  Goat: EAST
  Grass: EAST


The cost was: 7.0
Previous
Next Post »