docstr: :param K: candidates lists
  :param U: min resource each candidate needs
  :return:
docstr_tok: [":","param","K",":","candidates","lists",":","param","U",":","min","resource","each","candidate","needs",":","return",":"]
code: def pre_calculate_epoch_required(self, K, U):
      """
      :param K: candidates lists
      :param U: min resource each candidate needs
      :return:
      """
      total_epoch_each_rounds = K * U
      min_budget_required = 0
  
      previous_epoch = None
      while True:
          cur_cand_num = K
          if cur_cand_num == 1:
              break
          # number of each res given to each cand, pick lower bound
          epoch_per_model = int(total_epoch_each_rounds / cur_cand_num)
          if previous_epoch is None:
              previous_epoch = epoch_per_model
          elif previous_epoch == epoch_per_model:
              # which means the epoch don't increase, no need to re-evaluate each component
              K = cur_cand_num - 1
              continue
  
          if epoch_per_model >= self.max_unit_per_model:
              epoch_per_model = self.max_unit_per_model
          # evaluate each arch
          min_budget_required += epoch_per_model * cur_cand_num
          # sort from min to max
          if epoch_per_model == self.max_unit_per_model:
              # each model is fully evaluated, just return top 1
              K = 1
          else:
              # only keep 1/eta, pick lower bound
              K = cur_cand_num - 1
      return min_budget_required
  
imports: from copy import copy
  from src.common.constant import Config
label_desc: Use image node_id 3 for calling the BudgetAwareControllerSR obj's underlying member method code with example usage: obj.pre_calculate_epoch_required(K, U) and returns: min_budget_required