def linear_crossover(genome_1: Genome, genome_2: Genome) -> Genome: a: float = rd.uniform(0, 1) new_genes = (genome_1.genes * a + (1 - a) * genome_2.genes) for i in range(len(new_genes)): new_genes[i] = round(new_genes[i], 0) return Genome(new_genes)
def multi_point_crossover(genome_1: Genome, genome_2: Genome) -> Genome: num_of_points = randint(0, const.GENOME_LENGTH) selection = rd.choices([0, 1], weights=[5, 5], k=1) new_genes = [] multi_points = [] for i in range(num_of_points): multi_points.append(randint(0, const.GENOME_LENGTH)) # remove duplicate variables from the list multi_points = list(dict.fromkeys(multi_points)) multi_points.sort() counter = 0 if selection[0] == 0: for i in range(const.GENOME_LENGTH): if i >= multi_points[counter]: counter += 1 if counter % 2 == 0: new_genes.append(genome_1.genes[i]) else: new_genes.append(genome_2.genes[i]) else: for i in range(const.GENOME_LENGTH): if i >= multi_points[counter]: counter += 1 if counter % 2 == 0: new_genes.append(genome_2.genes[i]) else: new_genes.append(genome_1.genes[i]) return Genome(new_genes)
def uniform_crossover(genome_1: Genome, genome_2: Genome) -> Genome: new_genes = [] for i in range(const.GENOME_LENGTH): selection = rd.choices([0, 1], weights=[5, 5], k=1) if selection[0] == 0: new_genes.append(genome_1.genes[i]) else: new_genes.append(genome_2.genes[i]) return Genome(new_genes)
def one_point_crossover(genome_1: Genome, genome_2: Genome) -> Genome: first_point = randint(0, const.GENOME_LENGTH) new_genes = [] for i in range(const.GENOME_LENGTH): if first_point < i: new_genes.append(genome_1.genes[i]) else: new_genes.append(genome_2.genes[i]) return Genome(new_genes)
def two_point_crossover(genome_1: Genome, genome_2: Genome) -> Genome: first_point = randint(0, const.GENOME_LENGTH) # Normally both have to be a random number but it makes sense to start them that way since after the 1st point then the second starts second_point = randint(first_point, const.GENOME_LENGTH) new_genes = [] selection = rd.choices([0, 1], weights=[5, 5], k=1) if selection[0] == 0: for i in range(const.GENOME_LENGTH): if i < first_point or i > second_point: new_genes.append(genome_1.genes[i]) else: new_genes.append(genome_2.genes[i]) else: for i in range(const.GENOME_LENGTH): if i < first_point or i > second_point: new_genes.append(genome_2.genes[i]) else: new_genes.append(genome_1.genes[i]) return Genome(new_genes)
def __init__(self, individuals: List = None): if individuals is None: self.individuals: List[Genome] = [Genome() for _ in range(Const.N_INDIVIDUALS)] else: self.individuals: List[Genome] = individuals
def generate_new(self, next_population): while len(next_population) < N_INDIVIDUALS: next_population.append(Genome())
def arithmetic_crossover(genome_1: Genome, genome_2: Genome) -> Genome: new_genes = [] for i in range(const.GENOME_LENGTH): new_genes.append((genome_1.genes[i] + genome_2.genes[i]) / 2) return Genome(new_genes)