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):
        """
        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.

        """
        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