Gets the largest hyperband schedule within target_budget.
        This is required since the original hyperband algorithm uses R,
        the maximum number of resources per configuration.
        TODO(maxlam): Possibly binary search it if this becomes a bottleneck.

        Args:
            budget: total budget of the schedule.
            proportion_discard: hyperband parameter that specifies
                the proportion of configurations to discard per iteration.

def get_largest_schedule_within_budget(self, budget, proportion_discard):
        """
        Gets the largest hyperband schedule within target_budget.
        This is required since the original hyperband algorithm uses R,
        the maximum number of resources per configuration.
        TODO(maxlam): Possibly binary search it if this becomes a bottleneck.

        Args:
            budget: total budget of the schedule.
            proportion_discard: hyperband parameter that specifies
                the proportion of configurations to discard per iteration.
        """

        # Exhaustively generate schedules and check if
        # they're within budget, adding to a list.
        valid_schedules_and_costs = []
        for R in range(1, budget):
            schedule = self.generate_hyperband_schedule(R, proportion_discard)
            cost = self.compute_schedule_cost(schedule)
            if cost <= budget:
                valid_schedules_and_costs.append((schedule, cost))

        # Choose a valid schedule that maximizes usage of the budget.
        valid_schedules_and_costs.sort(key=lambda x: x[1], reverse=True)
        return valid_schedules_and_costs[0][0]