001    package aima.probability.reasoning;
002    
003    import java.util.ArrayList;
004    import java.util.Arrays;
005    import java.util.List;
006    
007    import aima.util.Matrix;
008    import aima.util.Table;
009    
010    /**
011     * @author Ravi Mohan
012     * 
013     */
014    
015    public class TransitionModel {
016    
017            private Table<String, String, Double> table;
018    
019            private List<String> states;
020    
021            public TransitionModel(List<String> states, List<String> actions) {
022                    this.states = states;
023                    List<String> state_actions = new ArrayList<String>();
024                    for (String state : states) {
025                            for (String action : actions) {
026                                    state_actions.add(state.concat(action));
027                            }
028                    }
029                    table = new Table<String, String, Double>(state_actions, states);
030            }
031    
032            public TransitionModel(List<String> states) {
033                    // no actions possible thus the only "action" is to "wait" till the next
034                    // perception is observed
035                    this(states, Arrays.asList(new String[] { HmmConstants.DO_NOTHING }));
036            }
037    
038            public void setTransitionProbability(String startState, String endState,
039                            Double probability) {
040                    String start_state_plus_action = startState
041                                    .concat(HmmConstants.DO_NOTHING);
042                    table.set(start_state_plus_action, endState, probability);
043            }
044    
045            public void setTransitionProbability(String startState, String action,
046                            String endState, Double probability) {
047                    String start_state_plus_action = startState.concat(action);
048                    table.set(start_state_plus_action, endState, probability);
049            }
050    
051            public double get(String old_state_action, String newState) {
052    
053                    return table.get(old_state_action, newState);
054            }
055    
056            public Matrix asMatrix(String action) {
057                    Matrix transitionMatrix = new Matrix(states.size(), states.size());
058                    for (int i = 0; i < states.size(); i++) {
059                            String oldState = states.get(i);
060                            String old_state_action = oldState.concat(action);
061                            for (int j = 0; j < states.size(); j++) {
062                                    String newState = states.get(j);
063                                    double transitionProbability = get(old_state_action, newState);
064                                    transitionMatrix.set(i, j, transitionProbability);
065                            }
066                    }
067                    return transitionMatrix;
068            }
069    
070            public Matrix asMatrix() {
071                    return asMatrix(HmmConstants.DO_NOTHING);
072            }
073    
074            public Matrix unitMatrix() {
075                    Matrix m = asMatrix();
076                    return Matrix.identity(m.getRowDimension(), m.getColumnDimension());
077            }
078    
079            public String getStateForProbability(String oldState, double probability) {
080    
081                    return getStateForGivenActionAndProbability(oldState,
082                                    HmmConstants.DO_NOTHING, probability);
083            }
084    
085            public String getStateForProbability(String oldState, String action,
086                            double probability) {
087    
088                    return getStateForGivenActionAndProbability(oldState, action,
089                                    probability);
090            }
091    
092            public String getStateForGivenActionAndProbability(String oldState,
093                            String action, double probability) {
094                    String state_action = oldState + action;
095    
096                    double total = 0.0;
097                    for (String state : states) {
098                            total += table.get(state_action, state);
099                            if (total >= probability) {
100                                    return state;
101                            }
102                    }
103                    return null;
104            }
105    
106    }