class_docstr: This hyperparameter space optimizer is similar to a grid search, however, it does
  try to greedily sample maximally different points in the space to explore it. This space
  optimizer has a fixed pseudorandom exploration method that makes the sampling reproductible.
  
  When over the expected_n_trials (if sampling too much), the sampler will turn
  to a non-seeded random search.
  
  It may be good for space exploration before a TPE or for unit tests.
  
  If the expected_n_trials is not set or set to 0, the sampler will guess its ideal
  sampling count and then switch to random search after that.
class_docstr_tok: ["This","hyperparameter","space","optimizer","is","similar","to","a","grid","search",",","however",",","it","does","try","to","greedily","sample","maximally","different","points","in","the","space","to","explore","it",".","This","space","optimizer","has","a","fixed","pseudorandom","exploration","method","that","makes","the","sampling","reproductible",".","When","over","the","expected_n_trials","(","if","sampling","too","much",")",",","the","sampler","will","turn","to","a","non-seeded","random","search",".","It","may","be","good","for","space","exploration","before","a","TPE","or","for","unit","tests",".","If","the","expected_n_trials","is","not","set","or","set","to","0",",","the","sampler","will","guess","its","ideal","sampling","count","and","then","switch","to","random","search","after","that","."]
docstr: Generate the grid of hyperparameters to pick from.
  
  :param hp_space: hyperparameter space
docstr_tok: ["Generate","the","grid","of","hyperparameters","to","pick","from",".",":","param","hp_space",":","hyperparameter","space"]
code: def _generate_grid(self, hp_space: HyperparameterSpace):
      """
      Generate the grid of hyperparameters to pick from.
  
      :param hp_space: hyperparameter space
      """
      # Start with discrete params:
      for hp_name, hp_dist in hp_space.to_flat_dict().items():
          if isinstance(hp_dist, DiscreteHyperparameterDistribution):
              hp_samples: List[Any] = hp_dist.values()
  
              reordered_hp_samples = self._pseudo_shuffle_list(
                  hp_samples
              )
              self.flat_hp_grid_values[hp_name] = reordered_hp_samples
              self.flat_hp_grid_lens.append(len(reordered_hp_samples))
  
      # Then fill the remaining continous params using the expected_n_trials:
      remainder: int = max(3, self.expected_n_trials)
      for hp_name, hp_dist in hp_space.to_flat_dict().items():
          if isinstance(hp_dist, ContinuousHyperparameterDistribution):
              hp_samples: List[Any] = [
                  hp_dist.mean(),
                  hp_dist.min()
                  if hp_dist.is_discrete()
                  else hp_dist._pseudo_min(),
                  hp_dist.max()
                  if hp_dist.is_discrete()
                  else hp_dist._pseudo_max(),
                  hp_dist.mean() + hp_dist.std(),
                  hp_dist.mean() - hp_dist.std(),
                  hp_dist.mean() + hp_dist.std() / 2,
                  hp_dist.mean() - hp_dist.std() / 2,
                  hp_dist.mean() + hp_dist.std() * 1.5,
                  hp_dist.mean() - hp_dist.std() * 1.5,
                  hp_dist.mean() + hp_dist.std() / 4,
                  hp_dist.mean() - hp_dist.std() / 4,
                  hp_dist.mean() + hp_dist.std() * 2.5,
                  hp_dist.mean() - hp_dist.std() * 2.5,
              ]
  
              def _ensure_unique(
                  value: Any, _unique_set: Set[Any]
              ) -> bool:
                  # remove duplicates such as when (or if) STD is of 0.
                  try:
                      ret = value not in _unique_set
                      _unique_set.add(value)
                      return ret
                  except BaseException:
                      return True
  
              _unique_set: Set[Any] = set()
              hp_samples: List[Any] = [
                  x
                  for x in hp_samples[:remainder]
                  if x in hp_dist
                  and not (math.isinf(x) or math.isnan(x))
                  and _ensure_unique(x, _unique_set)
              ]
              self.flat_hp_grid_values[hp_name] = hp_samples
              self.flat_hp_grid_lens.append(len(hp_samples))
  
      _estimated_ideal_n_trials: int = sum(self.flat_hp_grid_lens)
      _space_max = reduce(operator.mul, self.flat_hp_grid_lens, 1)
  
      if not (
          _estimated_ideal_n_trials
          <= self.expected_n_trials
          <= _space_max
      ):
          _new_val = max(
              min(_space_max, self.expected_n_trials),
              _estimated_ideal_n_trials,
          )
          warnings.warn(
              f"Warning: changed {self.__class__.__name__}.expected_n_trials from "
              f"{self.expected_n_trials} to {_new_val}. RandomSearch will be used "
              f"as a fallback past this point if needed."
          )
          self.expected_n_trials = _new_val
  
      self._i = 1
  
imports: import copy
  import itertools
  import math
  import operator
  import random
  import warnings
  from abc import ABC, abstractmethod
  from collections import OrderedDict
  from functools import reduce
  from typing import Any, List, Set, Tuple
  from neuraxle.hyperparams.distributions import ContinuousHyperparameterDistribution, DiscreteHyperparameterDistribution
  from neuraxle.hyperparams.space import FlatDict, HyperparameterSamples, HyperparameterSpace
  from neuraxle.metaopt.data.reporting import RoundReport
label_desc: Use image node_id 5 for calling the GridExplorationSampler obj's underlying member method code with example usage: obj._generate_grid(hp_space) and returns: ret, True