109 lines
5.2 KiB
Python
109 lines
5.2 KiB
Python
import random
|
|
|
|
class Crossover_Methods:
|
|
|
|
class Population:
|
|
"""Methods for selecting chromosomes to crossover."""
|
|
|
|
def sequential_selection(ga):
|
|
"""Select sequential pairs from the mating pool.
|
|
Every parent is paired with the previous parent.
|
|
The first parent is paired with the last parent.
|
|
"""
|
|
|
|
mating_pool = ga.population.get_mating_pool()
|
|
|
|
for index in range(len(mating_pool)): # for each parent in the mating pool
|
|
ga.population.add_child( # add a child
|
|
ga.crossover_individual_impl( # by crossing
|
|
ga, #
|
|
mating_pool[index], # the parent and
|
|
mating_pool[index-1] # the previous parent
|
|
)
|
|
)
|
|
|
|
|
|
def random_selection(ga):
|
|
"""Select random pairs from the mating pool.
|
|
Every parent is paired with a random parent.
|
|
"""
|
|
|
|
mating_pool = ga.population.get_mating_pool()
|
|
|
|
for parent in mating_pool: # for each parent in the mating pool
|
|
ga.population.add_child( # add a child
|
|
ga.crossover_individual_impl( # by crossing
|
|
ga, #
|
|
parent, # the parent and
|
|
random.choice(mating_pool) # a random parent
|
|
)
|
|
)
|
|
|
|
|
|
class Individual:
|
|
"""Methods for crossing parents."""
|
|
|
|
def single_point(ga, parent_one, parent_two):
|
|
"""Cross two parents by swapping genes at one random point."""
|
|
|
|
swap_index = random.randint(0, parent_one.size()-1)
|
|
return ga.make_chromosome(parent_one.get_gene_list()[:swap_index] + parent_two.get_gene_list()[swap_index:])
|
|
|
|
|
|
def multi_point(ga, parent_one, parent_two):
|
|
"""Cross two parents by swapping genes at multiple points."""
|
|
pass
|
|
|
|
|
|
def uniform(ga, parent_1, parent_2):
|
|
"""Cross two parents by swapping all genes randomly."""
|
|
|
|
return ga.make_chromosome([ # Make a new chromosome
|
|
random.choice([gene_1, gene_2]) # by randomly selecting genes
|
|
for gene_1, gene_2 in zip(parent_1.gene_list, parent_2.gene_list)]) # from each parent
|
|
|
|
|
|
class Arithmetic:
|
|
"""Crossover methods for numerical genes."""
|
|
|
|
def int_random(ga, parent_1, parent_2):
|
|
"""Cross two parents by taking a random integer value between each of the genes."""
|
|
|
|
return ga.make_chromosome([ # Make a new chromosome
|
|
ga.make_gene(random.randint(*sorted([data_1, data_2]))) # by randomly selecting integer genes between
|
|
for data_1, data_2 in zip(iter(parent_1), iter(parent_2))]) # each parents' genes
|
|
|
|
|
|
def int_weighted(ga, parent_1, parent_2):
|
|
"""Cross two parents by taking a a weighted average of the genes."""
|
|
|
|
# the percentage of genes taken from the first gene
|
|
weight = 0.25
|
|
|
|
return ga.make_chromosome([ # Make a new chromosome
|
|
ga.make_gene(int( # filled with new integer genes
|
|
weight*data_1+(1-weight)*data_2 # with weight% from gene 1 and
|
|
)) # (100-weight)% from gene 2
|
|
for data_1, data_2 in zip(iter(parent_1), iter(parent_2))]) # from each parents' genes
|
|
|
|
|
|
def float_random(ga, parent_one, parent_two):
|
|
"""Cross two parents by taking a random numeric value between each of the genes."""
|
|
|
|
return ga.make_chromosome([ # Make a new chromosome
|
|
ga.make_gene(random.uniform([data_1, data_2])) # by randomly selecting integer genes between
|
|
for data_1, data_2 in zip(iter(parent_1), iter(parent_2))]) # from each parents' genes
|
|
|
|
|
|
def float_weighted(ga, parent_one, parent_two):
|
|
"""Cross two parents by taking a a weighted average of the genes."""
|
|
|
|
# the percentage of genes taken from the first gene
|
|
weight = 0.25
|
|
|
|
return ga.make_chromosome([ # Make a new chromosome
|
|
ga.make_gene( # filled with new float genes
|
|
weight*data_1+(1-weight)*data_2 # with weight% from gene 1 and
|
|
) # (100-weight)% from gene 2
|
|
for data_1, data_2 in zip(iter(parent_1), iter(parent_2))]) # from each parents' genes
|