コード例 #1
0
def method1(ga): # Method 1 performs serial loops for crossover/mutation
    # Store parameters for readability
    population = ga.population
    pop_size = ga.ga_params['pop_size']
    percent_crossover = ga.ga_params['percent_crossover']
    percent_mutation = ga.ga_params['percent_mutation']
    num_elite = ga.ga_params['num_elite']

    # Sort population by fitness score (lowest score = most fit)
    population.sort(key=lambda x: x.fitness_score)

    # Calculate parents needed for crossover, ensure even number
    num_crossover = round((pop_size-num_elite)*percent_crossover)
    if (num_crossover % 2) != 0:  # If odd, increment by 1
        num_crossover += 1
    # Calculate parents needed for mutation
    num_mutation = round((pop_size-num_elite)*percent_mutation)
    # Calculate remaining number of trusses in next population
    num_random = pop_size - num_elite - num_crossover - num_mutation
    if num_random < 0:  # Raise exception if input params are unreasonable
        raise RuntimeError('Invalid GenAlg parameters.')

    # Instantiate objects
    selector = Selector(ga.selector_params)
    crossover = Crossover(ga.crossover_params)
    mutator = Mutator(ga.mutator_params)

    # Select parents as indices in current population
    crossover_parents = selector(num_crossover, population)
    mutation_parents = selector(num_mutation, population)

    # Save most fit trusses as elites
    pop_elite = population[:num_elite]

    # Portion of new population formed by crossover
    pop_crossover = []
    for i in range(0, num_crossover, 2):
        parentindex1 = crossover_parents[i]
        parentindex2 = crossover_parents[i+1]
        parent1 = population[parentindex1]
        parent2 = population[parentindex2]
        child1, child2 = crossover(parent1, parent2)
        pop_crossover.extend((child1, child2))

    # Portion of new population formed by mutation
    pop_mutation = []
    for i in range(num_mutation):
        parentindex = mutation_parents[i]
        parent = population[parentindex]
        child = mutator(parent)
        pop_mutation.append(child)

    # Create new random trusses with remaining spots in generation
    pop_random = [ga.generate_random(2) for i in range(num_random)]

    # Append separate lists to form new generation
    population = pop_elite + pop_crossover + pop_mutation + pop_random

    # Update population attribute
    return population
コード例 #2
0
    def test_sanity(self):
        """Test to make sure parent arrays of 1's returns all 1's."""
        array1 = np.ones((10, 1))
        array2 = np.ones((10, 1))
        check = np.ones((10, 1))

        children = Crossover.two_points_split(array1, array2)

        np.testing.assert_array_equal(children[0], check)
        np.testing.assert_array_equal(children[1], check)
コード例 #3
0
    def testZeros(self):
        """Test to make sure parent arrays of 0s returns 0s."""

        truss_1 = np.zeros(10, dtype=int)
        truss_2 = np.zeros(10, dtype=int)

        result = Crossover.uniform_crossover(truss_1, truss_2)

        np.testing.assert_array_equal(result[0], truss_1)
        np.testing.assert_array_equal(result[1], truss_2)
コード例 #4
0
    def testChildInParents(self):
        """Test to make sure that all values of the child arrays 
        exist in the one of the two parent arrays."""

        truss_1 = np.random.randint(10, size=25)
        truss_2 = np.random.randint(10, size=25)
        parents_combined = np.concatenate((truss_1, truss_2))

        result = Crossover.uniform_crossover(truss_1, truss_2)

        child1_status = str(np.all(np.in1d(result[0], parents_combined)))
        child2_status = str(np.all(np.in1d(result[1], parents_combined)))

        np.testing.assert_string_equal(child1_status, str(True))
        np.testing.assert_string_equal(child2_status, str(True))
コード例 #5
0
    def test_datatype(self):
        """Test to make sure the data type matches what is expected."""
        array1 = np.ones((10, 1), dtype=int)
        array2 = np.ones((10, 1), dtype=int)
        check = np.ones((10, 1), dtype=int)

        children = Crossover.single_point_split(array1, array2)

        np.testing.assert_array_equal(children[0], check)
        np.testing.assert_array_equal(children[1], check)

        np.testing.assert_string_equal(str((children[0]).dtype),
                                       str(check.dtype))
        np.testing.assert_string_equal(str((children[1]).dtype),
                                       str(check.dtype))
コード例 #6
0
    def testOutputTypeInt(self):
        """Test to make sure the data type matches what is expected."""

        truss_1 = np.zeros(10, dtype=int)
        truss_2 = np.zeros(10, dtype=int)
        check = np.zeros(10, dtype=int)

        result = Crossover.uniform_crossover(truss_1, truss_2)

        np.testing.assert_array_equal(result[0], check)
        np.testing.assert_array_equal(result[1], check)

        np.testing.assert_string_equal(str((result[0]).dtype),
                                       str(check.dtype))
        np.testing.assert_string_equal(str((result[1]).dtype),
                                       str(check.dtype))
コード例 #7
0
ファイル: genalg.py プロジェクト: vishalbelsare/GASTOp
    def update_population(self):  # Cristian
        ''' Creates new population by performing crossover and mutation, as well
        as taking elites and randomly generating trusses.

        First sorts the population by fitness score, from most fit to least fit.
        Creates selector object from population and method. Calls selector to
        get list of parents for crossover and mutation. Performs crossover and
        mutation.

        Args:
            None

        Returns:
            None
        '''

        # Store parameters for readability
        population = self.population
        pop_size = self.ga_params['pop_size']
        percent_crossover = self.ga_params['percent_crossover']
        percent_mutation = self.ga_params['percent_mutation']
        num_elite = self.ga_params['num_elite']

        # Sort population by fitness score (lowest score = most fit)
        # population.sort(key=lambda x: x.fitness_score) #remove

        # Calculate parents needed for crossover, ensure even number
        num_crossover = round((pop_size - num_elite) * percent_crossover)
        if (num_crossover % 2) != 0:  # If odd, decrement by 1
            num_crossover -= 1
        # Calculate parents needed for mutation
        num_mutation = round((pop_size - num_elite) * percent_mutation)
        # Calculate remaining number of trusses in next population
        num_random = pop_size - num_elite - num_crossover - num_mutation
        if num_random < 0:  # Raise exception if input params are unreasonable
            raise RuntimeError('percent_crossover + percent_mutation > 1')

        # Instantiate objects
        selector = Selector(self.selector_params)
        crossover = Crossover(self.crossover_params)
        mutator = Mutator(self.mutator_params)

        # Select parents as indices in current population
        crossover_parents = selector(num_crossover, population)
        mutation_parents = selector(num_mutation, population)

        # Save most fit trusses as elites
        pop_elite = population[:num_elite]

        pbar = tqdm(total=(num_crossover + num_mutation + num_random),
                    desc='Updating',
                    position=1)
        # Portion of new population formed by crossover
        pop_crossover = []
        for i in range(0, num_crossover, 2):
            parentindex1 = crossover_parents[i]
            parentindex2 = crossover_parents[i + 1]
            parent1 = population[parentindex1]
            parent2 = population[parentindex2]
            child1, child2 = crossover(parent1, parent2)
            pop_crossover.extend((child1, child2))
            pbar.update(2)

        # Portion of new population formed by mutation
        pop_mutation = []
        for i in range(num_mutation):
            parentindex = mutation_parents[i]
            parent = population[parentindex]
            child = mutator(parent)
            pop_mutation.append(child)
            pbar.update()

        # Create new random trusses with remaining spots in generation
        pop_random = []
        for i in range(num_random):
            pop_random.append(self.generate_random())
            pbar.update()

        # Append separate lists to form new generation
        population = pop_elite + pop_crossover + pop_mutation + pop_random
        pbar.close()
        # Update population attribute
        self.population = population
        return