class_docstr: Implementation of SMAC's local search.
  
  Parameters
  ----------
  configspace : ConfigurationSpace
  acquisition_function : AbstractAcquisitionFunction
  challengers : int, defaults to 5000
      Number of challengers.
  max_steps: int | None, defaults to None
      Maximum number of iterations that the local search will perform.
  n_steps_plateau_walk: int, defaults to 10
      Number of steps during a plateau walk before local search terminates.
  vectorization_min_obtain : int, defaults to 2
      Minimal number of neighbors to obtain at once for each local search for vectorized calls. Can be tuned to
      reduce the overhead of SMAC.
  vectorization_max_obtain : int, defaults to 64
      Maximal number of neighbors to obtain at once for each local search for vectorized calls. Can be tuned to
      reduce the overhead of SMAC.
  seed : int, defaults to 0
class_docstr_tok: ["Implementation","of","SMAC","'s","local","search",".","Parameters","--","--","--","--","--","configspace",":","ConfigurationSpace","acquisition_function",":","AbstractAcquisitionFunction","challengers",":","int",",","defaults","to","5000","Number","of","challengers",".","max_steps",":","int","|","None",",","defaults","to","None","Maximum","number","of","iterations","that","the","local","search","will","perform",".","n_steps_plateau_walk",":","int",",","defaults","to","10","Number","of","steps","during","a","plateau","walk","before","local","search","terminates",".","vectorization_min_obtain",":","int",",","defaults","to","2","Minimal","number","of","neighbors","to","obtain","at","once","for","each","local","search","for","vectorized","calls",".","Can","be","tuned","to","reduce","the","overhead","of","SMAC",".","vectorization_max_obtain",":","int",",","defaults","to","64","Maximal","number","of","neighbors","to","obtain","at","once","for","each","local","search","for","vectorized","calls",".","Can","be","tuned","to","reduce","the","overhead","of","SMAC",".","seed",":","int",",","defaults","to","0"]
docstr: Generate a set of initial points from the previous configurations and possibly additional points.
  
  The idea is to decouple runhistory from the local search model and replace it with a more general
  form (list[Configuration]). This is useful to more quickly collect new configurations
  along the iterations, rather than feeding it to the runhistory every time.
  
  create three lists and concatenate them:
  1. sorted the previous configs by acquisition value
  2. sorted the previous configs by marginal predictive costs
  3. additional start points
  
  and create a list that carries unique configurations only. Crucially,
  when reading from left to right, all but the first occurrence of a configuration
  are dropped.
  
  Parameters
  ----------
  previous_configs: list[Configuration]
      Previous configuration (e.g., from the runhistory).
  n_points: int
      Number of initial points to be generated.
  additional_start_points: list[tuple[float, Configuration]] | None
      Additional starting points.
  
  Returns
  -------
  init_points: list[Configuration]
      A list of initial points.
docstr_tok: ["Generate","a","set","of","initial","points","from","the","previous","configurations","and","possibly","additional","points",".","The","idea","is","to","decouple","runhistory","from","the","local","search","model","and","replace","it","with","a","more","general","form","(","list","[","Configuration","]",")",".","This","is","useful","to","more","quickly","collect","new","configurations","along","the","iterations",",","rather","than","feeding","it","to","the","runhistory","every","time",".","create","three","lists","and","concatenate","them",":","1.","sorted","the","previous","configs","by","acquisition","value","2.","sorted","the","previous","configs","by","marginal","predictive","costs","3.","additional","start","points","and","create","a","list","that","carries","unique","configurations","only",".","Crucially",",","when","reading","from","left","to","right",",","all","but","the","first","occurrence","of","a","configuration","are","dropped",".","Parameters","--","--","--","--","--","previous_configs",":","list","[","Configuration","]","Previous","configuration","(","e.g.",",","from","the","runhistory",")",".","n_points",":","int","Number","of","initial","points","to","be","generated",".","additional_start_points",":","list","[","tuple","[","float",",","Configuration","]","]","|","None","Additional","starting","points",".","Returns","--","--","--","-","init_points",":","list","[","Configuration","]","A","list","of","initial","points","."]
code: def _get_init_points_from_previous_configs(
      self,
      previous_configs: list[Configuration],
      n_points: int,
      additional_start_points: list[tuple[float, Configuration]] | None,
  ) -> list[Configuration]:
      """
      Generate a set of initial points from the previous configurations and possibly additional points.
  
      The idea is to decouple runhistory from the local search model and replace it with a more general
      form (list[Configuration]). This is useful to more quickly collect new configurations
      along the iterations, rather than feeding it to the runhistory every time.
  
      create three lists and concatenate them:
      1. sorted the previous configs by acquisition value
      2. sorted the previous configs by marginal predictive costs
      3. additional start points
  
      and create a list that carries unique configurations only. Crucially,
      when reading from left to right, all but the first occurrence of a configuration
      are dropped.
  
      Parameters
      ----------
      previous_configs: list[Configuration]
          Previous configuration (e.g., from the runhistory).
      n_points: int
          Number of initial points to be generated.
      additional_start_points: list[tuple[float, Configuration]] | None
          Additional starting points.
  
      Returns
      -------
      init_points: list[Configuration]
          A list of initial points.
      """
      assert self._acquisition_function is not None
  
      # configurations with the highest previous EI
      configs_previous_runs_sorted = self._sort_by_acquisition_value(
          previous_configs
      )
      configs_previous_runs_sorted = [
          conf[1] for conf in configs_previous_runs_sorted[:n_points]
      ]
  
      # configurations with the lowest predictive cost, check for None to make unit tests work
      if self._acquisition_function.model is not None:
          conf_array = convert_configurations_to_array(previous_configs)
          costs = self._acquisition_function.model.predict_marginalized(
              conf_array
          )[0]
          assert len(conf_array) == len(costs), (
              conf_array.shape,
              costs.shape,
          )
  
          # In case of the predictive model returning the prediction for more than one objective per configuration
          # (for example multi-objective or EIPS) it is not immediately clear how to sort according to the cost
          # of a configuration. Therefore, we simply follow the ParEGO approach and use a random scalarization.
          if len(costs.shape) == 2 and costs.shape[1] > 1:
              weights = np.array(
                  [self._rng.rand() for _ in range(costs.shape[1])]
              )
              weights = weights / np.sum(weights)
              costs = costs @ weights
  
          # From here: make argsort result to be random between equal values
          # http://stackoverflow.com/questions/20197990/how-to-make-argsort-result-to-be-random-between-equal-values
          random = self._rng.rand(len(costs))
          indices = np.lexsort(
              (random.flatten(), costs.flatten())
          )  # Last column is primary sort key!
  
          # Cannot use zip here because the indices array cannot index the
          # rand_configs list, because the second is a pure python list
          previous_configs_sorted_by_cost = [
              previous_configs[ind] for ind in indices
          ][:n_points]
      else:
          previous_configs_sorted_by_cost = []
  
      if additional_start_points is not None:
          additional_start_points = [
              asp[1] for asp in additional_start_points[:n_points]
          ]
      else:
          additional_start_points = []
  
      init_points = []
      init_points_as_set: set[Configuration] = set()
      for cand in itertools.chain(
          configs_previous_runs_sorted,
          previous_configs_sorted_by_cost,
          additional_start_points,
      ):
          if cand not in init_points_as_set:
              init_points.append(cand)
              init_points_as_set.add(cand)
  
      return init_points
  
file_path: SMAC3/smac/acquisition/maximizer/local_search.py
imports: from __future__ import annotations
  from typing import Any
  import itertools
  import time
  import numpy
  from ConfigSpace import Configuration, ConfigurationSpace
  from ConfigSpace.exceptions import ForbiddenValueError
  from smac.acquisition.function import AbstractAcquisitionFunction
  from smac.acquisition.maximizer.abstract_acqusition_maximizer import AbstractAcquisitionMaximizer
  from smac.utils.configspace import convert_configurations_to_array, get_one_exchange_neighbourhood
  from smac.utils.logging import get_logger
label_desc: Use image node_id 5 for calling the LocalSearch obj's underlying member method code with example usage: obj._get_init_points_from_previous_configs(previous_configs, n_points, additional_start_points) and returns: init_points