
    -ji-                       S SK Jr  S SKJr  S SKJr  S SKrS SKJr  S SKJ	r	  S SKJ
r
  S SKJr  S SKrS S	KJr  S S
KJr  S SKJr  S SKJr  S SKJr  S SKJr  S SKJr  \
(       a  S SKJr  \\\\\ S4   r!\" \"5      r# " S S\5      r$g)    )annotations)Mapping)SequenceN)Real)Any)TYPE_CHECKING)Union)optuna_warn)BaseDistribution)
get_logger)BaseSampler)LazyRandomState)FrozenTrial)
TrialState)Studyc                      \ rS rSrSr S     SS jjrSS jrSS jr      SS jr        SS jr	          SS	 jr
          SS
 jr\SS j5       rSS jr\SS j5       rSS jrSS jrSrg)GridSampler    ab  Sampler using grid search.

With :class:`~optuna.samplers.GridSampler`, the trials suggest all combinations of parameters
in the given search space during the study.

Example:

    .. testcode::

        import optuna


        def objective(trial):
            x = trial.suggest_float("x", -100, 100)
            y = trial.suggest_int("y", -100, 100)
            return x**2 + y**2


        search_space = {"x": [-50, 0, 50], "y": [-99, 0, 99]}
        study = optuna.create_study(sampler=optuna.samplers.GridSampler(search_space))
        study.optimize(objective)

Note:

    This sampler with :ref:`ask_and_tell` raises :exc:`RuntimeError` just after evaluating
    the final grid. This is because :class:`~optuna.samplers.GridSampler` automatically
    stops the optimization if all combinations in the passed ``search_space`` have already
    been evaluated, internally invoking the :func:`~optuna.study.Study.stop` method.
    As a workaround, we need to handle the error manually as in
    https://github.com/optuna/optuna/issues/4121#issuecomment-1305289910.

Note:

    :class:`~optuna.samplers.GridSampler` does not take care of a parameter's quantization
    specified by discrete suggest methods but just samples one of values specified in the
    search space. E.g., in the following code snippet, either of ``-0.5`` or ``0.5`` is
    sampled as ``x`` instead of an integer point.

    .. testcode::

        import optuna


        def objective(trial):
            # The following suggest method specifies integer points between -5 and 5.
            x = trial.suggest_float("x", -5, 5, step=1)
            return x**2


        # Non-int points are specified in the grid.
        search_space = {"x": [-0.5, 0.5]}
        study = optuna.create_study(sampler=optuna.samplers.GridSampler(search_space))
        study.optimize(objective, n_trials=2)

Note:
    A parameter configuration in the grid is not considered finished until its trial is
    finished. Therefore, during distributed optimization where trials run concurrently,
    different workers will occasionally suggest the same parameter configuration.
    The total number of actual trials may therefore exceed the size of the grid.

Note:
    All parameters must be specified when using :class:`~optuna.samplers.GridSampler` with
    :meth:`~optuna.study.Study.enqueue_trial`.

Args:
    search_space:
        A dictionary whose key and value are a parameter name and the corresponding candidates
        of values, respectively.
    seed:
        A seed to fix the order of trials as the grid is randomly shuffled. This shuffle is
        beneficial when the number of grids is larger than ``n_trials`` in
        :meth:`~optuna.Study.optimize` to suppress suggesting similar grids. Please note
        that fixing ``seed`` for each process is strongly recommended in distributed
        optimization to avoid duplicated suggestions.
Nc                ^   UR                  5        H  u  p4U H  nU R                  X55        M     M!     0 U l        [        UR                  5       5       H  u  p4[	        U5      U R                  U'   M     [	        [
        R                  " U R                  R                  5       6 5      U l        [        UR                  5       5      U l
        [        U R                  5      U l        [        U=(       d    S5      U l        U R                  R                  R!                  U R                  5        g )Nr   )items_check_value_search_spacesortedlist	itertoolsproductvalues
_all_gridskeys_param_nameslen_n_min_trialsr   _rngrngshuffle)selfsearch_spaceseed
param_nameparam_valuesvalues         O/home/james-whalen/.local/lib/python3.13/site-packages/optuna/samplers/_grid.py__init__GridSampler.__init__m   s     )5(:(:(<$J%!!*4 & )=  (.|/A/A/C(D$J-1,-?Dz* )E y00$2D2D2K2K2MNO"<#4#4#67 1#DIA.			doo.    c                L    U R                   R                  R                  5         g N)r#   r$   r(   )r&   s    r,   
reseed_rngGridSampler.reseed_rng~   s    		r/   c                $   SUR                   ;   d  SUR                   ;   a  g SUR                  ::  a}  UR                  U R                  :  ac  UR                  R	                  UR
                  SU R                  5        UR                  R	                  UR
                  SUR                  5        g U R                  U5      n[        U5      S:X  a<  [        R                  S5        [        [        [        U R                  5      5      5      n[        U R                  R                   R#                  U5      5      nUR                  R	                  UR
                  SU R                  5        UR                  R	                  UR
                  SU5        g )Ngrid_idfixed_paramsr   r'   z`GridSampler` is re-evaluating a configuration because the grid has been exhausted. This may happen due to a timing issue during distributed optimization or when re-running optimizations on already finished studies.)system_attrsnumberr"   _storageset_trial_system_attr	_trial_idr   _get_unvisited_grid_idsr!   _loggerwarningr   ranger   intr#   r$   choice)r&   studytrialtarget_gridsr5   s        r,   before_trialGridSampler.before_trial   s)    ***n@R@R.R0B0B!BNN001C1C NN00)U\\Z33E:|!
 OOP  c$//&: ;<L diimm**<89,,U__ndN`N`a,,U__iQr/   c                    0 $ r1    )r&   rB   rC   s      r,   infer_relative_search_space'GridSampler.infer_relative_search_space   	     	r/   c                    0 $ r1   rH   )r&   rB   rC   r'   s       r,   sample_relativeGridSampler.sample_relative   rK   r/   c           	     l   SUR                   ;  a  Sn[        U5      eX0R                  ;  a  SU S3n[        U5      eUR                   S   nU R                  U   U R                  R                  U5         nUR                  UR                  U5      5      nU(       d  [        SU SU SU S35        U$ )	Nr5   zKAll parameters must be specified when using GridSampler with enqueue_trial.zThe parameter name, z!, is not found in the given grid.zThe value `z$` is out of range of the parameter `z;`. The value will be used but the actual distribution is: `z`.)	r7   
ValueErrorr   r   r    index	_containsto_internal_reprr
   )	r&   rB   rC   r)   param_distributionmessager5   param_valuecontainss	            r,   sample_independentGridSampler.sample_independent   s     E...cGW%%///,ZL8YZGW%%$$Y/oog.t/@/@/F/Fz/RS%//0B0S0ST_0`ak]*Nzl [KK]J^^`b
 r/   c                   U R                  U5      n[        U5      S:X  a  UR                  5         g [        U5      S:X  aB  UR                  R	                  UR
                  5      S   nXeS   :X  a  UR                  5         g g g )Nr      r5   )r<   r!   stopr9   get_trial_system_attrsr;   )r&   rB   rC   stater   rD   r5   s          r,   after_trialGridSampler.after_trial   sq     33E:|!JJL!#nn;;EOOLYWGq/)

 * $r/   c                    Ub%  [        U[        [        [        [        45      (       a  g U  S[        U5       S3n[        U5        g )Nz# contains a value with the type of z, which is not supported by `GridSampler`. Please make sure a value is `str`, `int`, `float`, `bool` or `None` for persistent storage.)
isinstancestrr@   floatbooltyper
   )r)   rV   rU   s      r,   r   GridSampler._check_value   sP    *[3UD:Q"R"R l=d;>O=P QG G 	
 	Gr/   c                   / n/ nUR                   R                  UR                  SS9nU H  nSUR                  ;   d  M  U R	                  UR                  S   5      (       d  M:  UR
                  R                  5       (       a   UR                  UR                  S   5        My  UR
                  [        R                  :X  d  M  UR                  UR                  S   5        M     [        [        U R                  5      5      [        U5      -
  [        U5      -
  n[        U5      S:X  a*  [        [        U R                  5      5      [        U5      -
  n[        U5      $ )NF)deepcopyr5   r'   r   )r9   get_all_trials	_study_idr7   _same_search_spacer^   is_finishedappendr   RUNNINGsetr?   r"   r!   r   )r&   rB   visited_gridsrunning_gridstrialstunvisited_gridss          r,   r<   #GridSampler._get_unvisited_grid_ids   s   
 ..u.OAANN*t/F/F~.0 0 77&&((!((	)BCWW
 2 22!((	)BC  eD$6$6783};MMPSTaPbb 1$!%(:(:";<s=?QQOO$$r/   c                   [        U [        5      =(       a    [        R                  " [	        U 5      5      n[        U[        5      =(       a    [        R                  " [	        U5      5      nX:H  =(       d    U=(       a    U$ r1   )rb   r   npisnanrd   )value1value2value1_is_nanvalue2_is_nans       r,   _grid_value_equalGridSampler._grid_value_equal  sQ    "640LRXXeFm5L"640LRXXeFm5L Fm&EFr/   c                   [        UR                  5       5      [        U R                  R                  5       5      :w  a  gUR                  5        Hk  n[        X   5      [        U R                  U   5      :w  a    g[	        X   5       H.  u  p4U R                  X@R                  U   U   5      (       a  M-      g   Mm     g)NFT)rp   r   r   r!   	enumerater~   )r&   r'   r)   irV   s        r,   rl   GridSampler._same_search_space  s    |  "#s4+=+=+B+B+D'EE&++-J<+,D4F4Fz4R0SS"+L,D"E--k;M;Mj;YZ[;\]]  #F	 . r/   c                <    [        U R                  U5      5      S:H  $ )zO
Return True if all the possible params are evaluated, otherwise return False.
r   )r!   r<   )r&   rB   s     r,   is_exhaustedGridSampler.is_exhausted  s     4//671<<r/   )r   r"   r    r#   r   r1   )r'   %Mapping[str, Sequence[GridValueType]]r(   z
int | NonereturnNone)r   r   )rB   r   rC   r   r   r   )rB   r   rC   r   r   dict[str, BaseDistribution])rB   r   rC   r   r'   r   r   zdict[str, Any])
rB   r   rC   r   r)   rc   rT   r   r   r   )
rB   r   rC   r   r^   r   r   zSequence[float] | Noner   r   )r)   rc   rV   r   r   r   )rB   r   r   z	list[int])rz   GridValueTyper{   r   r   re   )r'   r   r   re   )rB   r   r   re   )__name__
__module____qualname____firstlineno____doc__r-   r2   rE   rI   rM   rX   r_   staticmethodr   r<   r~   rl   r   __static_attributes__rH   r/   r,   r   r       s   JZ W[/A/IS/	/"'RR#.	$
#.>Y	
  	
 - 
4  	
 ' 
  	 	%8 G G
=r/   r   )%
__future__r   collections.abcr   r   r   numbersr   typingr   r   r	   numpyrx   optuna._warningsr
   optuna.distributionsr   optuna.loggingr   optuna.samplersr   "optuna.samplers._lazy_random_stater   optuna.trialr   r   optuna.studyr   rc   rd   r@   re   r   r   r=   r   rH   r/   r,   <module>r      sn    " # $        ( 1 % ' > $ # " c5#tT12 X
~=+ ~=r/   