docs: def simulated_annealing(problem, schedule=_exp_schedule, iterations_limit=0, viewer=None):
      '''
      Simulated annealing.
  
      schedule is the scheduling function that decides the chance to choose worst
      nodes depending on the time.
      If iterations_limit is specified, the algorithm will end after that
      number of iterations. Else, it will continue until it can't find a
      better node than the current one.
      Requires: SearchProblem.actions, SearchProblem.result, and
      SearchProblem.value.
      '''
      return _local_search(problem,
                           _create_simulated_annealing_expander(schedule),
                           iterations_limit=iterations_limit,
                           fringe_size=1,
                           stop_when_no_better=iterations_limit==0,
                           viewer=viewer)