def value_iteration(env, gamma, epsilon):
    ' Solves the shortest path problem using value iteration\n        :input town_map env           : The town_map environment in which we seek to\n                                    find the shortest path.\n        :input float gamma        : The discount factor.\n        :input float epsilon      : accuracy of the value iteration procedure.\n        :return numpy.array V     : Optimal values for every state at every\n                                    time, dimension S*T\n        :return numpy.array policy: Optimal time-varying policy at every state,\n                                    dimension S*T\n    '
    p = env.transition_probabilities
    r = env.rewards
    n_states = env.n_states
    n_actions = env.n_actions
    V = np.zeros(n_states)
    Q = np.zeros((n_states, n_actions))
    BV = np.zeros(n_states)
    n = 0
    tol = (((1 - gamma) * epsilon) / gamma)
    for s in range(n_states):
        for a in range(n_actions):
            Q[(s, a)] = (r[(s, a)] + (gamma * np.dot(p[:, s, a], V)))
    BV = np.max(Q, 1)
    while ((np.linalg.norm((V - BV)) >= tol) and (n < 2600)):
        n += 1
        V = np.copy(BV)
        for s in range(n_states):
            for a in range(n_actions):
                Q[(s, a)] = (r[(s, a)] + (gamma * np.dot(p[:, s, a], V)))
        BV = np.max(Q, 1)
    policy = np.argmax(Q, 1)
    return (V, policy)
Solves the shortest path problem using value iteration
:input town_map env           : The town_map environment in which we seek to
                            find the shortest path.
:input float gamma        : The discount factor.
:input float epsilon      : accuracy of the value iteration procedure.
:return numpy.array V     : Optimal values for every state at every
                            time, dimension S*T
:return numpy.array policy: Optimal time-varying policy at every state,
                            dimension S*T
def value_iteration(env, gamma, epsilon):
    ' Solves the shortest path problem using value iteration\n        :input town_map env           : The town_map environment in which we seek to\n                                    find the shortest path.\n        :input float gamma        : The discount factor.\n        :input float epsilon      : accuracy of the value iteration procedure.\n        :return numpy.array V     : Optimal values for every state at every\n                                    time, dimension S*T\n        :return numpy.array policy: Optimal time-varying policy at every state,\n                                    dimension S*T\n    '
    p = env.transition_probabilities
    r = env.rewards
    n_states = env.n_states
    n_actions = env.n_actions
    V = np.zeros(n_states)
    Q = np.zeros((n_states, n_actions))
    BV = np.zeros(n_states)
    n = 0
    tol = (((1 - gamma) * epsilon) / gamma)
    for s in range(n_states):
        for a in range(n_actions):
            Q[(s, a)] = (r[(s, a)] + (gamma * np.dot(p[:, s, a], V)))
    BV = np.max(Q, 1)
    while ((np.linalg.norm((V - BV)) >= tol) and (n < 2600)):
        n += 1
        V = np.copy(BV)
        for s in range(n_states):
            for a in range(n_actions):
                Q[(s, a)] = (r[(s, a)] + (gamma * np.dot(p[:, s, a], V)))
        BV = np.max(Q, 1)
    policy = np.argmax(Q, 1)
    return (V, policy)