class_docstr: Base class for Hoeffding Decision Trees.
  
  This is an **abstract class**, so it cannot be used directly. It defines base operations
  and properties that all the Hoeffding decision trees must inherit or implement according to
  their own design.
  
  Parameters
  ----------
  max_depth
      The maximum depth a tree can reach. If `None`, the tree will grow indefinitely.
  binary_split
      If True, only allow binary splits.
  max_size
      The max size of the tree, in Megabytes (MB).
  memory_estimate_period
      Interval (number of processed instances) between memory consumption checks.
  stop_mem_management
      If True, stop growing as soon as memory limit is hit.
  remove_poor_attrs
      If True, disable poor attributes to reduce memory usage.
  merit_preprune
      If True, enable merit-based tree pre-pruning.
docstr: Compute the Hoeffding bound, used to decide how many samples are necessary at each
  node.
  
  Notes
  -----
  The Hoeffding bound is defined as:
  
  $\\epsilon = \\sqrt{\\frac{R^2\\ln(1/\\delta))}{2n}}$
  
  where:
  
  $\\epsilon$: Hoeffding bound.
  $R$: Range of a random variable. For a probability the range is 1, and for an
  information gain the range is log *c*, where *c* is the number of classes.
  $\\delta$: Confidence. 1 minus the desired probability of choosing the correct
  attribute at any given node.
  $n$: Number of samples.
  
  Parameters
  ----------
  range_val
      Range value.
  confidence
      Confidence of choosing the correct attribute.
  n
      Number of processed samples.
code: def _hoeffding_bound(range_val, confidence, n):
      r"""Compute the Hoeffding bound, used to decide how many samples are necessary at each
      node.
  
      Notes
      -----
      The Hoeffding bound is defined as:
  
      $\\epsilon = \\sqrt{\\frac{R^2\\ln(1/\\delta))}{2n}}$
  
      where:
  
      $\\epsilon$: Hoeffding bound.
      $R$: Range of a random variable. For a probability the range is 1, and for an
      information gain the range is log *c*, where *c* is the number of classes.
      $\\delta$: Confidence. 1 minus the desired probability of choosing the correct
      attribute at any given node.
      $n$: Number of samples.
  
      Parameters
      ----------
      range_val
          Range value.
      confidence
          Confidence of choosing the correct attribute.
      n
          Number of processed samples.
      """
      return math.sqrt(
          (range_val * range_val * math.log(1.0 / confidence))
          / (2.0 * n)
      )
  
imports: from __future__ import annotations
  import collections
  import functools
  import io
  import math
  from abc import ABC, abstractmethod
  from river import base
  from river.utils.norm import normalize_values_in_dict
  from .nodes.branch import DTBranch, NominalBinaryBranch, NominalMultiwayBranch, NumericBinaryBranch, NumericMultiwayBranch
  from .nodes.leaf import HTLeaf
  from .utils import calculate_object_size
label_desc: Use image node_id 2 for calling the HoeffdingTree obj's underlying member method code with example usage: obj._hoeffding_bound(range_val, confidence, n) and returns: math