import random


def evolve(pop, mutate_rate, mu, lambda_):
    """
    :param pop: populations of the parents
    :param mutate_rate: default rate is 0.02 in function mutate
    :param mu: select the size of parents who behave better
    :param lambda_: size of the mutated children
    :return: a new populations
    """
    pop = sorted(pop, key=lambda individual: individual.score)
    parents = pop[-mu:]
    # generate lambda new children via mutation
    offspring = []
    for i in range(lambda_ - 3):
        parent = random.choice(parents)
        offspring.append(parent.mutate(mutate_rate))
    best = pop[-1]
    second_best = pop[-2]
    for i in range(3):
        offspring.append(best.mutate(mutate_rate - 0.01))
        offspring.append(second_best.mutate(mutate_rate - 0.01))
    return parents + offspring