docs: def random_combinations(items, size, num=None, rng=None):
      """
      Yields `num` combinations of length `size` from items in random order
  
      Args:
          items (?):
          size (?):
          num (None): (default = None)
          rng (RandomState):  random number generator(default = None)
  
      Yields:
          tuple: combo
  
      CommandLine:
          python -m utool.util_iter random_combinations
  
      Example:
          >>> # ENABLE_DOCTEST
          >>> from utool.util_iter import *  # NOQA
          >>> import utool as ut
          >>> items = list(range(10))
          >>> size = 3
          >>> num = 5
          >>> rng = 0
          >>> combos = list(random_combinations(items, size, num, rng))
          >>> result = ('combos = %s' % (ut.repr2(combos),))
          >>> print(result)
  
      Example:
          >>> # ENABLE_DOCTEST
          >>> from utool.util_iter import *  # NOQA
          >>> import utool as ut
          >>> items = list(zip(range(10), range(10)))
          >>> size = 3
          >>> num = 5
          >>> rng = 0
          >>> combos = list(random_combinations(items, size, num, rng))
          >>> result = ('combos = %s' % (ut.repr2(combos),))
          >>> print(result)
      """
      import scipy.misc
      import numpy as np
      import utool as ut
      rng = ut.ensure_rng(rng, impl='python')
      num_ = np.inf if num is None else num
      # Ensure we dont request more than is possible
      n_max = int(scipy.misc.comb(len(items), size))
      num_ = min(n_max, num_)
      if num is not None and num_ > n_max // 2:
          # If num is too big just generate all combinations and shuffle them
          combos = list(it.combinations(items, size))
          rng.shuffle(combos)
          for combo in combos[:num]:
              yield combo
      else:
          # Otherwise yield randomly until we get something we havent seen
          items = list(items)
          combos = set()
          while len(combos) < num_:
              # combo = tuple(sorted(rng.choice(items, size, replace=False)))
              combo = tuple(sorted(rng.sample(items, size)))
              if combo not in combos:
                  # TODO: store indices instead of combo values
                  combos.add(combo)
                  yield combo