def step(individuals):
    """
    Runs a single generation of the evolutionary algorithm process:
        Selection
        Variation
        Evaluation
        Replacement
    
    :param individuals: The current generation, upon which a single
    evolutionary generation will be imposed.
    :return: The next generation of the population.
    """

    # Select parents from the original population.
    parents = selection(individuals)

    # Crossover parents and add to the new population.
    cross_pop = crossover(parents)

    # Mutate the new population.
    new_pop = mutation(cross_pop)

    # Evaluate the fitness of the new population.
    new_pop = evaluate_fitness(new_pop)

    # Replace the old population with the new population.
    individuals = replacement(new_pop, individuals)

    # Generate statistics for run so far
    get_stats(individuals)

    return individuals
Example #2
0
    def act(self):
        # Process the information if the agent has sense nearby agents
        if self.agents_found:

            # Combine the original individual and individuals found by interacting with nearby agents to form
            # a population
            individuals = self.individual + self.nearby_agents

            # Find out parents from the population
            parents = selection(individuals)

            # Crossover parents and add to the new population.
            cross_pop = crossover(parents)

            # Mutate the new population.
            new_pop = mutation(cross_pop)

            # Evaluate the fitness of the new population.
            new_pop = evaluate_fitness(new_pop)

            # Replace the old population with the new population.
            individuals = replacement(new_pop, individuals)

            # Generate statistics for run so far
            get_stats(individuals)

            # Sort the individuals list
            individuals.sort(reverse=True)

            # Get the higest performing individual from the sorted population
            self.new_individual = individuals[0]
def steady_state(individuals):
    """
    Runs a single generation of the evolutionary algorithm process,
    using steady state replacement:
        Selection
        Variation
        Evaluation
        Replacement
        
    Steady state replacement uses the Genitor model (Whitley, 1989) whereby
    new individuals directly replace the worst individuals in the population
    regardless of whether or not the new individuals are fitter than those
    they replace. Note that traditional GP crossover generates only 1 child,
    whereas linear GE crossover (and thus all crossover functions used in
    PonyGE) generates 2 children from 2 parents. Thus, we use a deletion
    strategy of 2.

    :param individuals: The current generation, upon which a single
    evolutionary generation will be imposed.
    :return: The next generation of the population.
    """

    # Initialise counter for new individuals.
    ind_counter = 0

    while ind_counter < params['POPULATION_SIZE']:

        # Select parents from the original population.
        parents = selection(individuals)

        # Perform crossover on selected parents.
        cross_pop = crossover_inds(parents[0], parents[1])

        if cross_pop is None:
            # Crossover failed.
            pass

        else:
            # Mutate the new population.
            new_pop = mutation(cross_pop)

            # Evaluate the fitness of the new population.
            new_pop = evaluate_fitness(new_pop)

            # Sort the original population
            individuals.sort(reverse=True)

            # Combine both populations
            total_pop = individuals[:-len(new_pop)] + new_pop

            # Increment the ind counter
            ind_counter += params['GENERATION_SIZE']

    # Return the combined population.
    return total_pop
Example #4
0
    def __init__(self, ip):
        # Interaction probability received in constructor
        self.interaction_probability = ip

        # Only initialize singel individual. Single agent can only have single genetic information
        self.individual = initialisation(1)

        # Evaluate the fitness for the the individual
        self.individual = evaluate_fitness(self.individual)

        # Flag which store the boolean value for other nebouring agents found or not
        self.agents_found = False
def search_loop():
    """
    This is a standard search process for an evolutionary algorithm. Loop over
    a given number of generations.
    
    :return: The final population after the evolutionary process has run for
    the specified number of generations.
    """

    if params['MULTICORE']:
        # initialize pool once, if mutlicore is enabled
        params['POOL'] = Pool(processes=params['CORES'],
                              initializer=pool_init,
                              initargs=(params, ))  # , maxtasksperchild=1)

    # Initialise population
    individuals = initialisation(params['POPULATION_SIZE'])

    # Evaluate initial population
    individuals = evaluate_fitness(individuals)

    # Generate statistics for run so far
    get_stats(individuals)

    # Traditional GE
    for generation in range(1, (params['GENERATIONS'] + 1)):
        stats['gen'] = generation

        # New generation
        individuals = params['STEP'](individuals)

    if params['MULTICORE']:
        # Close the workers pool (otherwise they'll live on forever).
        params['POOL'].close()

    return individuals
def LAHC_search_loop():
    """
    Search loop for Late Acceptance Hill Climbing.
    
    This is the LAHC pseudo-code from Burke and Bykov:

        Produce an initial solution best
        Calculate initial cost function C(best)
        Specify Lfa
        For all k in {0...Lfa-1} f_k := C(best)
        First iteration iters=0;
        Do until a chosen stopping condition
            Construct a candidate solution best*
            Calculate its cost function C(best*)
            idx := iters mod Lfa
            If C(best*)<=f_idx or C(best*)<=C(best)
            Then accept the candidate (best:=best*)
            Else reject the candidate (best:=best)
            Insert the current cost into the fitness array f_idx:=C(best)
            Increment the iteration number iters:=iters+1
    
    :return: The final population.
    """

    max_its = params['POPULATION_SIZE'] * params['GENERATIONS']

    # Initialise population
    individuals = params['INITIALISATION'](params['POPULATION_SIZE'])

    # Evaluate initial population
    individuals = evaluate_fitness(individuals)

    # Generate statistics for run so far
    get_stats(individuals)

    # Find the best individual so far.
    best = trackers.best_ever

    # Set history.
    Lfa = params['HILL_CLIMBING_HISTORY']
    history = [best for _ in range(Lfa)]

    # iters is the number of individuals examined so far.
    iters = len(individuals)

    for generation in range(1, (params['GENERATIONS'] + 1)):

        this_gen = []

        # even though there is no population, we will take account of
        # the pop size parameter: ie we'll save stats after every
        # "generation"
        for j in range(params['POPULATION_SIZE']):

            this_gen.append(best)  # collect this "generation"

            # Mutate the best to get the candidate best
            candidate_best = params['MUTATION'](best)
            if not candidate_best.invalid:
                candidate_best.evaluate()

            # Find the index of the relevant individual from the late
            # acceptance history.
            idx = iters % Lfa

            if candidate_best >= history[idx]:
                best = candidate_best  # Accept the candidate

            else:
                pass  # reject the candidate

            # Set the new best into the history.
            history[idx] = best

            # Increment evaluation counter.
            iters += 1

            if iters >= max_its:
                # We have completed the total number of iterations.
                break

        # Get stats for this "generation".
        stats['gen'] = generation
        get_stats(this_gen)

        if iters >= max_its:
            # We have completed the total number of iterations.
            break

    return individuals
def SCHC_search_loop():
    """
    Search Loop for Step-Counting Hill-Climbing.
    
    This is the SCHC pseudo-code from Bykov and Petrovic.

        Produce an initial solution best
        Calculate an initial cost function C(best)
        Initial cost bound cost_bound := C(best)
        Initial counter counter := 0
        Specify history
        Do until a chosen stopping condition
            Construct a candidate solution best*
            Calculate the candidate cost function C(best*)
            If C(best*) < cost_bound or C(best*) <= C(best)
                Then accept the candidate best := best*
                Else reject the candidate best := best
            Increment the counter counter := counter + 1
            If counter >= history
                Then update the bound cost_bound := C(best)
                reset the counter counter := 0
        
        Two alternative counting methods (start at the first If):
        
        SCHC-acp counts only accepted moves:
        
            If C(best*) < cost_bound or C(best*) <= C(best)
                Then accept the candidate best := best*
                     increment the counter counter := counter + 1
                Else reject the candidate best := best
            If counter >= history
                Then update the bound cost_bound := C(best)
                     reset the counter counter := 0
        
        SCHC-imp counts only improving moves:
        
            If C(best*) < C(best)
                Then increment the counter counter := counter + 1
            If C(best*) < cost_bound or C(best*) <= C(best)
                Then accept the candidate best := best*
                Else reject the candidate best := best
            If counter >= history
                Then update the bound cost_bound := C(best)
                     reset the counter counter := 0
    
    :return: The final population.
    """

    # Calculate maximum number of evaluation iterations.
    max_its = params['POPULATION_SIZE'] * params['GENERATIONS']
    count_method = params['SCHC_COUNT_METHOD']

    # Initialise population
    individuals = params['INITIALISATION'](params['POPULATION_SIZE'])

    # Evaluate initial population
    individuals = evaluate_fitness(individuals)

    # Generate statistics for run so far
    get_stats(individuals)

    # Set best individual and initial cost bound.
    best = trackers.best_ever
    cost_bound = best.deep_copy()

    # Set history and counter.
    history = params['HILL_CLIMBING_HISTORY']
    counter = 0

    # iters is the number of individuals examined/iterations so far.
    iters = len(individuals)

    for generation in range(1, (params['GENERATIONS'] + 1)):

        this_gen = []

        # even though there is no population, we will take account of
        # the pop size parameter: ie we'll save stats after every
        # "generation"
        for j in range(params['POPULATION_SIZE']):

            this_gen.append(best)  # collect this "generation"

            # Mutate best to get candidate best.
            candidate_best = params['MUTATION'](best)
            if not candidate_best.invalid:
                candidate_best.evaluate()

            # count
            if count_method == "count_all":  # we count all iterations (moves)
                counter += 1  # increment the counter

            elif count_method == "acp":  # we count accepted moves only
                if candidate_best > cost_bound or candidate_best >= best:
                    counter += 1  # increment the counter

            elif count_method == "imp":  # we count improving moves only
                if candidate_best > best:
                    counter += 1  # increment the counter

            else:
                s = "algorithm.hill_climbing.SCHC_search_loop\n" \
                    "Error: Unknown count method: %s" % (count_method)
                raise Exception(s)

            # accept
            if candidate_best > cost_bound or candidate_best >= best:
                best = candidate_best  # accept the candidate

            else:
                pass  # reject the candidate

            if counter >= history:
                cost_bound = best  # update the bound
                counter = 0  # reset the counter

            # Increment iteration counter.
            iters += 1

            if iters >= max_its:
                # We have completed the total number of iterations.
                break

        # Get stats for this "generation".
        stats['gen'] = generation
        get_stats(this_gen)

        if iters >= max_its:
            # We have completed the total number of iterations.
            break

    return individuals