code: def optimize(self, problem, max_iterations=100, max_seconds=float('inf'),
                   cache_encoded=True, cache_solution=False, clear_cache=True,
                   logging_func=_print_fitnesses,
                   n_processes=0):
          if not isinstance(problem, Problem):
              raise TypeError('problem must be an instance of Problem class')
          if n_processes > 0:
              try:
                  pool = multiprocessing.Pool(processes=n_processes)
              except NameError:
                  raise ImportError(
                      'pickle, dill, or multiprocessing library is not available.'
                  )
          else:
              pool = None
          self.__max_iterations = max_iterations
          self._reset()
          best_solution = {'solution': None, 'fitness': None}
          population = self.initial_population()
          try:
              start = time.clock()
              for self.iteration in itertools.count(1):
                  solutions, fitnesses, finished = self._get_fitnesses(
                      problem,
                      population,
                      cache_encoded=cache_encoded,
                      cache_solution=cache_solution,
                      pool=pool)
                  best_index, best_fitness = max(
                      enumerate(fitnesses), key=operator.itemgetter(1))
                  if best_fitness > best_solution['fitness']:
                      best_solution['fitness'] = best_fitness
                      best_solution['solution'] = solutions[best_index]
                  if logging_func:
                      logging_func(self.iteration, population, solutions,
                                   fitnesses, best_solution['solution'],
                                   best_solution['fitness'])
                  if finished:
                      self.solution_found = True
                      break
                  if time.clock() - start >= max_seconds:
                      break
                  if self.iteration >= max_iterations:
                      break
                  population = self.next_population(population, fitnesses)
              self.best_solution = best_solution['solution']
              self.best_fitness = best_solution['fitness']
          finally:
              if clear_cache:
                  self.__encoded_cache = {}
                  self.__solution_cache = {}
                  self._get_encoded_key = self._get_encoded_key_type
                  self._get_solution_key = self._get_solution_key_type
              try:
                  pool.terminate()
                  pool.close()
              except AttributeError:
                  assert pool is None
          return self.best_solution