'Builds a SubwordTextEncoder that has `vocab_size` near `target_size`.
Uses simple recursive binary search to find a minimum token count that most
closely matches the `target_size`.
Args:
target_size: Desired vocab_size to approximate.
token_counts: A dictionary of token counts, mapping string to int.
min_val: An integer; lower bound for the minimum token count.
max_val: An integer; upper bound for the minimum token count.
num_iterations: An integer; how many iterations of refinement.
Returns:
A SubwordTextEncoder instance.
Raises:
ValueError: If `min_val` is greater than `max_val`.'

@classmethod
def build_to_target_size(cls, target_size, token_counts, min_val, max_val, num_iterations=4):

    if (min_val > max_val):
        raise ValueError('Lower    bound    for    the    minimum    token    count    is    greater    than    the    upper    bound.')
    def bisect(min_val, max_val):
        'Bisection    to    find    the    right    size.'
        present_count = ((max_val + min_val) // 2)
        tf.logging.info(('Trying    min_count    %d' % present_count))
        subtokenizer = cls()
        subtokenizer.build_from_token_counts(token_counts, present_count, num_iterations)
        if ((subtokenizer.vocab_size == target_size) or (min_val >= max_val)):
            return subtokenizer
        if (subtokenizer.vocab_size > target_size):
            other_subtokenizer = bisect((present_count + 1), max_val)
        else:
            other_subtokenizer = bisect(min_val, (present_count - 1))
        if (other_subtokenizer is None):
            return subtokenizer
        if (abs((other_subtokenizer.vocab_size - target_size)) < abs((subtokenizer.vocab_size - target_size))):
            return other_subtokenizer
        return subtokenizer
    return bisect(min_val, max_val)
