class_docstr: !
  @brief Represent algorithm for searching optimal number of clusters using specified K-algorithm (K-Means,
          K-Medians, K-Medoids) that is based on Silhouette method.
  
  @details This algorithm uses average value of scores for estimation and applicable for clusters that are well
            separated. Here is an example where clusters are well separated (sample 'Hepta'):
  @code
      from pyclustering.cluster import cluster_visualizer
      from pyclustering.cluster.center_initializer import kmeans_plusplus_initializer
      from pyclustering.cluster.kmeans import kmeans
      from pyclustering.cluster.silhouette import silhouette_ksearch_type, silhouette_ksearch
      from pyclustering.samples.definitions import FCPS_SAMPLES
      from pyclustering.utils import read_sample
  
      sample = read_sample(FCPS_SAMPLES.SAMPLE_HEPTA)
      search_instance = silhouette_ksearch(sample, 2, 10, algorithm=silhouette_ksearch_type.KMEANS).process()
  
      amount = search_instance.get_amount()
      scores = search_instance.get_scores()
  
      print("Scores: '%s'" % str(scores))
  
      initial_centers = kmeans_plusplus_initializer(sample, amount).initialize()
      kmeans_instance = kmeans(sample, initial_centers).process()
  
      clusters = kmeans_instance.get_clusters()
  
      visualizer = cluster_visualizer()
      visualizer.append_clusters(clusters, sample)
      visualizer.show()
  @endcode
  
  Obtained Silhouette scores for each K:
  @code
  Scores: '{2: 0.418434, 3: 0.450906, 4: 0.534709, 5: 0.689970, 6: 0.588460, 7: 0.882674, 8: 0.804725, 9: 0.780189}'
  @endcode
  
  K = 7 has the bigger average Silhouette score and it means that it is optimal amount of clusters:
  @image html silhouette_ksearch_hepta.png "Silhouette ksearch's analysis with further K-Means clustering (sample 'Hepta')."
  
  @see silhouette_ksearch_type
docstr: !
  @brief Initialize Silhouette search algorithm to find out optimal amount of clusters.
  
  @param[in] data (array_like): Input data that is used for searching optimal amount of clusters.
  @param[in] kmin (uint): Minimum amount of clusters that might be allocated. Should be equal or greater than `2`.
  @param[in] kmax (uint): Maximum amount of clusters that might be allocated. Should be equal or less than amount
              of points in input data.
  @param[in] **kwargs: Arbitrary keyword arguments (available arguments: `algorithm`, `random_state`).
  
  <b>Keyword Args:</b><br>
      - algorithm (silhouette_ksearch_type): Defines algorithm that is used for searching optimal number of
         clusters (by default K-Means).
      - ccore (bool): If True then CCORE (C++ implementation of pyclustering library) is used (by default True).
docstr_tok: ["!","@","brief","Initialize","Silhouette","search","algorithm","to","find","out","optimal","amount","of","clusters",".","@","param","[","in","]","data","(","array_like",")",":","Input","data","that","is","used","for","searching","optimal","amount","of","clusters",".","@","param","[","in","]","kmin","(","uint",")",":","Minimum","amount","of","clusters","that","might","be","allocated",".","Should","be","equal","or","greater","than","`","2","`",".","@","param","[","in","]","kmax","(","uint",")",":","Maximum","amount","of","clusters","that","might","be","allocated",".","Should","be","equal","or","less","than","amount","of","points","in","input","data",".","@","param","[","in","]","*","*","kwargs",":","Arbitrary","keyword","arguments","(","available","arguments",":","`","algorithm","`",",","`","random_state","`",")",".","<","b",">","Keyword","Args",":","<","\/b",">","<","br",">","-","algorithm","(","silhouette_ksearch_type",")",":","Defines","algorithm","that","is","used","for","searching","optimal","number","of","clusters","(","by","default","K-Means",")",".","-","ccore","(","bool",")",":","If","True","then","CCORE","(","C++","implementation","of","pyclustering","library",")","is","used","(","by","default","True",")","."]
code: def __init__(self, data, kmin, kmax, **kwargs):
      """!
      @brief Initialize Silhouette search algorithm to find out optimal amount of clusters.
  
      @param[in] data (array_like): Input data that is used for searching optimal amount of clusters.
      @param[in] kmin (uint): Minimum amount of clusters that might be allocated. Should be equal or greater than `2`.
      @param[in] kmax (uint): Maximum amount of clusters that might be allocated. Should be equal or less than amount
                  of points in input data.
      @param[in] **kwargs: Arbitrary keyword arguments (available arguments: `algorithm`, `random_state`).
  
      <b>Keyword Args:</b><br>
          - algorithm (silhouette_ksearch_type): Defines algorithm that is used for searching optimal number of
             clusters (by default K-Means).
          - ccore (bool): If True then CCORE (C++ implementation of pyclustering library) is used (by default True).
  
      """
      self.__data = data
      self.__kmin = kmin
      self.__kmax = kmax
  
      self.__algorithm = kwargs.get(
          "algorithm", silhouette_ksearch_type.KMEANS
      )
      self.__random_state = kwargs.get("random_state", None)
      self.__return_index = (
          self.__algorithm == silhouette_ksearch_type.KMEDOIDS
      )
  
      self.__amount = -1
      self.__score = -1.0
      self.__scores = {}
  
      self.__verify_arguments()
  
      self.__ccore = kwargs.get("ccore", True)
      if self.__ccore:
          self.__ccore = ccore_library.workable()
  
imports: from enum import IntEnum
  import numpy
  from pyclustering.cluster.kmeans import kmeans
  from pyclustering.cluster.kmedians import kmedians
  from pyclustering.cluster.kmedoids import kmedoids
  from pyclustering.cluster.center_initializer import kmeans_plusplus_initializer
  from pyclustering.utils.metric import distance_metric, type_metric
  from pyclustering.core.wrapper import ccore_library
  from pyclustering.core.metric_wrapper import metric_wrapper
  import pyclustering.core.silhouette_wrapper
label_desc: Use image node_id 1 to create a new silhouette_ksearch object  with example: obj = silhouette_ksearch(data, kmin, kmax)