class_docstr: Abstract implementation of an intensifier supporting multi-fidelity, multi-objective, and multi-threading.
  The abstract intensifier keeps track of the incumbent, which is updated everytime the runhistory changes.
  
  Parameters
  ----------
  n_seeds : int | None, defaults to None
      How many seeds to use for each instance. It is used in the abstract intensifier to determine validation trials.
  max_config_calls : int, defaults to None
      Maximum number of configuration evaluations. Basically, how many instance-seed keys should be max evaluated
      for a configuration. It is used in the abstract intensifier to determine validation trials.
  max_incumbents : int, defaults to 10
      How many incumbents to keep track of in the case of multi-objective.
  seed : int, defaults to None
      Internal seed used for random events like shuffle seeds.
class_docstr_tok: ["Abstract","implementation","of","an","intensifier","supporting","multi-fidelity",",","multi-objective",",","and","multi-threading",".","The","abstract","intensifier","keeps","track","of","the","incumbent",",","which","is","updated","everytime","the","runhistory","changes",".","Parameters","--","--","--","--","--","n_seeds",":","int","|","None",",","defaults","to","None","How","many","seeds","to","use","for","each","instance",".","It","is","used","in","the","abstract","intensifier","to","determine","validation","trials",".","max_config_calls",":","int",",","defaults","to","None","Maximum","number","of","configuration","evaluations",".","Basically",",","how","many","instance-seed","keys","should","be","max","evaluated","for","a","configuration",".","It","is","used","in","the","abstract","intensifier","to","determine","validation","trials",".","max_incumbents",":","int",",","defaults","to","10","How","many","incumbents","to","keep","track","of","in","the","case","of","multi-objective",".","seed",":","int",",","defaults","to","None","Internal","seed","used","for","random","events","like","shuffle","seeds","."]
docstr: Returns a list of instance-seed keys. Considers seeds and instances from the
  runhistory (``self._tf_seeds`` and ``self._tf_instances``). If no seeds or instances were found, new
  seeds and instances are generated based on the global intensifier seed.
  
  Warning
  -------
  The passed seed is only used for validation. For training, the global intensifier seed is used.
  
  Parameters
  ----------
  validate : bool, defaults to False
      Whether to get validation trials or training trials. The only difference lies in different seeds.
  seed : int | None, defaults to None
      The seed used for the validation trials.
  
  Returns
  -------
  instance_seed_keys : list[InstanceSeedKey]
      Instance-seed keys of interest.
code: def get_instance_seed_keys_of_interest(
      self,
      *,
      validate: bool = False,
      seed: int | None = None,
  ) -> list[InstanceSeedKey]:
      """Returns a list of instance-seed keys. Considers seeds and instances from the
      runhistory (``self._tf_seeds`` and ``self._tf_instances``). If no seeds or instances were found, new
      seeds and instances are generated based on the global intensifier seed.
  
      Warning
      -------
      The passed seed is only used for validation. For training, the global intensifier seed is used.
  
      Parameters
      ----------
      validate : bool, defaults to False
          Whether to get validation trials or training trials. The only difference lies in different seeds.
      seed : int | None, defaults to None
          The seed used for the validation trials.
  
      Returns
      -------
      instance_seed_keys : list[InstanceSeedKey]
          Instance-seed keys of interest.
      """
      if self._runhistory is None:
          raise RuntimeError(
              "Please set the runhistory before calling this method."
          )
  
      if len(self._tf_instances) == 0:
          raise RuntimeError(
              "Please call __post_init__ before calling this method."
          )
  
      if seed is None:
          seed = 0
  
      # We cache the instance-seed keys for efficiency and consistency reasons
      if (self._instance_seed_keys is None and not validate) or (
          self._instance_seed_keys_validation is None and validate
      ):
          instance_seed_keys: list[InstanceSeedKey] = []
          if validate:
              rng = np.random.RandomState(seed)
          else:
              rng = self._rng
  
          i = 0
          while True:
              found_enough_configs = (
                  self._max_config_calls is not None
                  and len(instance_seed_keys) >= self._max_config_calls
              )
              used_enough_seeds = (
                  self._n_seeds is not None and i >= self._n_seeds
              )
  
              if found_enough_configs or used_enough_seeds:
                  break
  
              if validate:
                  next_seed = int(
                      rng.randint(low=0, high=MAXINT, size=1)[0]
                  )
              else:
                  try:
                      next_seed = self._tf_seeds[i]
                      logger.info(
                          f"Added existing seed {next_seed} from runhistory to the intensifier."
                      )
                  except IndexError:
                      # Use global random generator for a new seed and mark it so it will be reused for another config
                      next_seed = int(
                          rng.randint(low=0, high=MAXINT, size=1)[0]
                      )
  
                      # This line here is really important because we don't want to add the same seed twice
                      if next_seed in self._tf_seeds:
                          continue
  
                      self._tf_seeds.append(next_seed)
                      logger.debug(
                          f"Added a new random seed {next_seed} to the intensifier."
                      )
  
              # If no instances are used, tf_instances includes None
              for instance in self._tf_instances:
                  instance_seed_keys.append(
                      InstanceSeedKey(instance, next_seed)
                  )
  
              # Only use one seed in deterministic case
              if self._scenario.deterministic:
                  logger.info(
                      "Using only one seed for deterministic scenario."
                  )
                  break
  
              # Seed counter
              i += 1
  
          # Now we cut so that we only have max_config_calls instance_seed_keys
          # We favor instances over seeds here: That makes sure we always work with the same instance/seed pairs
          if self._max_config_calls is not None:
              if len(instance_seed_keys) > self._max_config_calls:
                  instance_seed_keys = instance_seed_keys[
                      : self._max_config_calls
                  ]
                  logger.info(
                      f"Cut instance-seed keys to {self._max_config_calls} entries."
                  )
  
          # Set it globally
          if not validate:
              self._instance_seed_keys = instance_seed_keys
          else:
              self._instance_seed_keys_validation = instance_seed_keys
  
      if not validate:
          assert self._instance_seed_keys is not None
          instance_seed_keys = self._instance_seed_keys
      else:
          assert self._instance_seed_keys_validation is not None
          instance_seed_keys = self._instance_seed_keys_validation
  
      return instance_seed_keys.copy()
  
imports: from __future__ import annotations
  from abc import abstractmethod
  from typing import Any, Callable, Iterator
  import dataclasses
  import json
  from collections import defaultdict
  from pathlib import Path
  import numpy
  from ConfigSpace import Configuration
  import smac
  from smac.callback.callback import Callback
  from smac.constants import MAXINT
  from smac.main.config_selector import ConfigSelector
  from smac.runhistory import TrialInfo
  from smac.runhistory.dataclasses import InstanceSeedBudgetKey, InstanceSeedKey, TrajectoryItem, TrialValue
  from smac.runhistory.runhistory import RunHistory
  from smac.scenario import Scenario
  from smac.utils.configspace import get_config_hash, print_config_changes
  from smac.utils.logging import get_logger
  from smac.utils.pareto_front import calculate_pareto_front, sort_by_crowding_distance
label_desc: Use image node_id 17 for calling the AbstractIntensifier obj's underlying member method code with example usage: obj.get_instance_seed_keys_of_interest() and returns: instance_seed_keys