class_docstr: Implementation of Succesive Halving supporting multi-fidelity, multi-objective, and multi-processing.
  Internally, a tracker keeps track of configurations and their bracket and stage.
  
  The behaviour of this intensifier is as follows:
  
  - First, adds configurations from the runhistory to the tracker. The first stage is always filled-up. For example,
    the user provided 4 configs with the tell-method but the first stage requires 8 configs: 4 new configs are
    sampled and added together with the provided configs as a group to the tracker.
  - While loop:
  
    - If a trial in the tracker has not been yielded yet, yield it.
    - If we are running out of trials, we simply add a new batch of configurations to the first stage.
  
  Note
  ----
  The implementation natively supports brackets from Hyperband. However, in the case of Successive Halving,
  only one bracket is used.
  
  Parameters
  ----------
  eta : int, defaults to 3
      Input that controls the proportion of configurations discarded in each round of Successive Halving.
  n_seeds : int, defaults to 1
      How many seeds to use for each instance.
  instance_seed_order : str, defaults to "shuffle_once"
      How to order the instance-seed pairs. Can be set to:
  
      - `None`: No shuffling at all and use the instance-seed order provided by the user.
      - `shuffle_once`: Shuffle the instance-seed keys once and use the same order across all runs.
      - `shuffle`: Shuffles the instance-seed keys for each bracket individually.
  incumbent_selection : str, defaults to "highest_observed_budget"
      How to select the incumbent when using budgets. Can be set to:
  
      - `any_budget`: Incumbent is the best on any budget i.e., best performance regardless of budget.
      - `highest_observed_budget`: Incumbent is the best in the highest budget run so far.
      - `highest_budget`: Incumbent is selected only based on the highest budget.
  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.
code: def _get_max_iterations(
      eta: int, max_budget: float | int, min_budget: float | int
  ) -> int:
      return int(
          np.floor(np.log(max_budget / min_budget) / np.log(eta))
      )
  
imports: from __future__ import annotations
  from typing import Any, Iterator
  import math
  from collections import defaultdict
  import numpy
  from ConfigSpace import Configuration
  from smac.constants import MAXINT
  from smac.intensifier.abstract_intensifier import AbstractIntensifier
  from smac.runhistory import TrialInfo
  from smac.runhistory.dataclasses import InstanceSeedBudgetKey
  from smac.runhistory.errors import NotEvaluatedError
  from smac.scenario import Scenario
  from smac.utils.configspace import get_config_hash
  from smac.utils.data_structures import batch
  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 5 for calling the SuccessiveHalving obj's underlying member method code with example usage: obj._get_max_iterations(eta, max_budget, min_budget) and returns: int