import java.util.ArrayList; import java.util.Random; import java.util.Scanner; public class State { /** * Name of the state */ private String name; /** * Array of transition probabilities. There is exactly one * entry for each arrow in the Markov Chain diagram */ private ArrayList probability; /** * Array of cumulative probability transitions. This array is the same size as the * transition probability array. Entry i of this array is the sum of the transition * probabilities 0 ... i */ private ArrayList cumulativeProbability; /** * Array of next states. Each entry corresponds to one of hte arrows in the * Markov Chain diagram. Entry i corresponds to probability i */ private ArrayList nextState; /** * Indicate whether this is a terminal state. */ private boolean isTerminal; /** * Declaring a variable as "static" means that it is a "class variable". Any method * can reference it, but there is exactly one copy of this variable, no matter how * many instances are created. In other words, all object instances share the same * "random". */ private static Random random = new Random(); /** * Seed the class random number generator * @param seed Value used to seed the random number generator */ public static void seedRandom(int seed){ random = new Random(seed); } /** * Constructor: must initialize all instance variables * @param name Name of the state. */ public State(String name){ // "this.name" refers to the class variable. "name" refers to the parameter this.name = name; ////////////////////////////////////////////////////////////////////////// // Add the rest of the implementation here ////////////////////////////////////////////////////////////////////////// } /** * Add a transition to the Markov Chain. * * Note: all of the arrays are updated by this method. Remember that the * first transition may be handled just a bit differently than the other transitions * (depends on your implementation) * * @param probability Probability of the transition * @param nextState State to which to transition */ public void addTransition(double probability, State nextState){ ////////////////////////////////////////////////////////////////////////// // Add the rest of the implementation here ////////////////////////////////////////////////////////////////////////// } /** * Set whether the current state is a terminal state or not * * @param isTerminal true = state is a terminal state; false = state is not a terminal state */ public void setTerminal(boolean isTerminal){ this.isTerminal = isTerminal; } /** * Indicates whether the current state is a terminal state * * @return true if the state is a terminal state; false otherwise */ public boolean getTerminal(){ return isTerminal; } /** * Return the next state given the current state. * * Implementation hint: sample exactly one double from the random number generator. Use * this value to determine whether a transition to another state has occurred (by default, * there is no transition & "this" can be returned). Make use of the cumulativeProbability * variable to make this decision. * * @return The next state */ public State nextState(){ // Sample exactly one double double val = random.nextDouble(); ////////////////////////////////////////////////////////////////////////// // Add the rest of the implementation here // Hint: use cumulativeProbability to decide whether to transition to another State // Hint 2: remember that "this" will refer to the reference to the current object ////////////////////////////////////////////////////////////////////////// } /** * Describe the current instance * * @return String that describes the current instance */ public String toString(){ return name; } /** * Display the details of the current state. * Show: * - Name of the state & whether it is a terminal state * - Each of the transitions */ public void display(){ // Name of the state System.out.print(this); if(isTerminal) { System.out.print(" (Terminal)"); } System.out.println(":"); // Show the transitions if(probability.size() == 0) { // No transitions System.out.println("\tNO TRANSITIONS"); }else{ // Loop over each transition for(int i = 0; i < probability.size(); ++i){ System.out.println("\t" + probability.get(i) + "\t" + cumulativeProbability.get(i) + "\t" + nextState.get(i)); } } } /** * Prompt the user for a non-negative integer. If one is entered, then * it is returned. If the user enters the string "done", then Integer.MIN_VALUE * is returned. Otherwise, continue to reprompt the user. * * @param prompt String prompt to be displayed for the user requesting a specific non-negative integer * @param keyboard The Scanner to accept input through * @return A non-negative integer or Integer.MIN_VALUE (if "done" is entered) */ public static int getNonNegativeInt(String prompt, Scanner keyboard){ ////////////////////////////////////////////////////////////////////////// // Insert your implementation of this method ////////////////////////////////////////////////////////////////////////// } /** * Main function: * 1. Create the Markov Chain * 2. Display the Markov Chain * 3. Prompt for a random seed & seed the random number generator * 4. Follow the Markov Chain starting from the initial state */ public static void main(String[] args) { // Create the states State s0 = new State("No Precipitation"); State s1 = new State("Sleeting"); State s2 = new State("Snowing"); State s3 = new State("Classes Cancelled"); // Connect the states through the transitions ////////////////////////////////////////////////////////////////////////// // Add the rest of the implementation here ////////////////////////////////////////////////////////////////////////// // Set the terminals ////////////////////////////////////////////////////////////////////////// // Add the rest of the implementation here ////////////////////////////////////////////////////////////////////////// // Display the full Markov Chain s0.display(); s1.display(); s2.display(); s3.display(); System.out.println("######################\n"); // Prompt for a seed and seed the random number generator int seed; Scanner keyboard = new Scanner(System.in); do{ seed = getNonNegativeInt("Enter a seed: ", keyboard); }while(seed == Integer.MIN_VALUE); State.seedRandom(seed); // Starting from state s0, follow the Markov Chain until it reaches a terminal state State s = s0; // Traverse the Markov Chain ////////////////////////////////////////////////////////////////////////// // Add the rest of the implementation here ////////////////////////////////////////////////////////////////////////// // Display last state System.out.println(s); } }