def generational_replacement(random, population, parents, offspring, args):
    """Performs generational replacement with optional weak elitism.
    
    This function performs generational replacement, which means that
    the entire existing population is replaced by the offspring,
    truncating to the population size if the number of offspring is 
    larger. Weak elitism may also be specified through the `num_elites`
    keyword argument in args. If this is used, the best `num_elites`
    individuals in the current population are allowed to survive if
    they are better than the worst `num_elites` offspring.
    
    .. Arguments:
       random -- the random number generator object
       population -- the population of individuals
       parents -- the list of parent individuals
       offspring -- the list of offspring individuals
       args -- a dictionary of keyword arguments

    Optional keyword arguments in args:
    
    - *num_elites* -- number of elites to consider (default 0)
    
    """
    num_elites = args.setdefault('num_elites', 0)
    population.sort(reverse=True)
    offspring.extend(population[:num_elites])
    offspring.sort(reverse=True)
    survivors = offspring[:len(population)]
    return survivors