'Solve the dynamic programming problem.
Parameters
method : str, optinal(default=\'policy_iteration\')
Solution method, str in {\'value_iteration\', \'vi\',
\'policy_iteration\', \'pi\', \'modified_policy_iteration\',
\'mpi\'}.
v_init : array_like(float, ndim=1), optional(default=None)
Initial value function, of length n. If None, `v_init` is
set such that v_init(s) = max_a r(s, a) for value iteration
and policy iteration; for modified policy iteration,
v_init(s) = min_(s_next, a) r(s_next, a)/(1 - beta) to guarantee
convergence.
epsilon : scalar(float), optional(default=None)
Value for epsilon-optimality. If None, the value stored in
the attribute `epsilon` is used.
max_iter : scalar(int), optional(default=None)
Maximum number of iterations. If None, the value stored in
the attribute `max_iter` is used.
k : scalar(int), optional(default=20)
Number of iterations for partial policy evaluation in
modified policy iteration (irrelevant for other methods).
Returns
res : DPSolveResult
Optimization result represetned as a DPSolveResult. See
`DPSolveResult` for details.'

def solve(self, method='policy_iteration', v_init=None, epsilon=None, max_iter=None, k=20):

    if (method in ['value_iteration', 'vi']):
        res = self.value_iteration(v_init=v_init, epsilon=epsilon, max_iter=max_iter)
    elif (method in ['policy_iteration', 'pi']):
        res = self.policy_iteration(v_init=v_init, max_iter=max_iter)
    elif (method in ['modified_policy_iteration', 'mpi']):
        res = self.modified_policy_iteration(v_init=v_init, epsilon=epsilon, max_iter=max_iter, k=k)
    else:
        raise ValueError('invalid    method')
    return res
