code: def policy_iteration(mdp):
      "Solve an MDP by policy iteration [Fig. 17.7]"
      U = dict([(s, 0) for s in mdp.states])
      pi = dict([(s, random.choice(mdp.actions(s))) for s in mdp.states])
      while True:
          U = policy_evaluation(pi, U, mdp)
          unchanged = True
          for s in mdp.states:
              a = argmax(mdp.actions(s), lambda a: expected_utility(a,s,U,mdp))
              if a != pi[s]:
                  pi[s] = a
                  unchanged = False
          if unchanged:
              return pf policy_iteration(mdp):
      "Solve an MDP by policy iteration [Fig. 17.7]"
      U = dict([(s, 0) for s in mdp.states])
      pi = dict([(s, random.choice(mdp.actions(s))) for s in mdp.states])
      while True:
          U = policy_evaluation(pi, U, mdp)
          unchanged = True
          for s in mdp.states:
              a = argmax(mdp.actions(s), lambda a: expected_utility(a,s,U,mdp))
              if a != pi[s]:
                  pi[s] = a
                  unchanged = False
          if unchanged:
              return pi
docs: Solve an MDP by policy iteration [Fig. 17.7]