Generate hyperband schedule according to the paper.

        Args:
            R: maximum resources per config.
            eta: proportion of configruations to discard per
                iteration of successive halving.

        Returns: hyperband schedule, which is represented
            as a list of brackets, where each bracket
            contains a list of (num configurations,
            num resources to use per configuration).
            See the paper for more details.

def generate_hyperband_schedule(self, R, eta):
        """
        Generate hyperband schedule according to the paper.

        Args:
            R: maximum resources per config.
            eta: proportion of configruations to discard per
                iteration of successive halving.

        Returns: hyperband schedule, which is represented
            as a list of brackets, where each bracket
            contains a list of (num configurations,
            num resources to use per configuration).
            See the paper for more details.
        """
        schedule = []
        s_max = int(math.floor(math.log(R, eta)))
        # B = (s_max + 1) * R
        for s in range(0, s_max + 1):
            n = math.ceil(int((s_max + 1) / (s + 1)) * eta ** s)
            r = R * eta ** (-s)
            bracket = []
            for i in range(0, s + 1):
                n_i = int(math.floor(n * eta ** (-i)))
                r_i = int(r * eta ** i)
                bracket.append((n_i, r_i))
            schedule = [bracket] + schedule
        return schedule