def eval_genomes(genomes, config):
    """
    The function to evaluate the fitness of each genome in 
    the genomes list. 
    The provided configuration is used to create feed-forward 
    neural network from each genome and after that created
    the neural network evaluated in its ability to solve
    XOR problem. As a result of this function execution, the
    the fitness score of each genome updated to the newly
    evaluated one.
    Arguments:
        genomes: The list of genomes from population in the 
                current generation
        config: The configuration settings with algorithm
                hyper-parameters
    """
    for genome_id, genome in genomes:
        genome.fitness = 0.0
        net = neat.nn.FeedForwardNetwork.create(genome, config)
        fitness = cart.eval_fitness(net)
        if fitness >= config.fitness_threshold:
            # do additional steps of evaluation with random initial states
            # to make sure that we found stable control strategy rather than
            # special case for particular initial state
            success_runs = evaluate_best_net(net, config, additional_num_runs)
            # adjust fitness
            fitness = 1.0 - (additional_num_runs - success_runs) / \
                      additional_num_runs

        genome.fitness = fitness
def evaluate_best_net(net, config, num_runs):
    """
    The function to evaluate the ANN of the best genome in
    specified number of sequetial runs. It is aimed to test it
    against various random initial states that checks if it is
    implementing stable control strategy or just a special case
    for particular initial state.
    Arguments:
        net:        The ANN to evaluate
        config:     The hyper-parameters configuration
        num_runs:   The number of sequential runs
    Returns:
        The number of succesful runs 
    """
    for run in range(num_runs):
        fitness = cart.eval_fitness(net, max_bal_steps=additional_steps)
        if fitness < config.fitness_threshold:
            return run
    return num_runs
def eval_genomes(genomes, config):
    """
    The function to evaluate the fitness of each genome in 
    the genomes list.
    Arguments:
        genomes: The list of genomes from population in the 
                current generation
        config: The configuration settings with algorithm
                hyper-parameters
    """
    for genome_id, genome in genomes:
        genome.fitness = 0.0
        net = neat.nn.FeedForwardNetwork.create(genome, config)
        fitness = cart.eval_fitness(net)
        if fitness >= config.fitness_threshold:
            # do additional steps of evaluation with random initial states
            # to make sure that we found stable control strategy rather than
            # special case for particular initial state
            success_runs = evaluate_best_net(net, config, additional_num_runs)
            # adjust fitness
            fitness = 1.0 - (additional_num_runs - success_runs) / \
                      additional_num_runs

        genome.fitness = fitness