def ordered_crossover(ind1: Individual, ind2: Individual) -> Tuple[Individual, Individual]: """ Mate two individuals by recombining their respective topology order. This operator produces two offsprings, where each inherits the unchanged adjacency matrix of a parent. :param ind1: The first individual participating in the crossover. :param ind2: The second individual participating in the crossover. :returns: A tuple of two offsprings. """ if ind1 == ind2: return ind1, ind2 # turn list of topologies into a list of indices cols = sorted(ind1.topology) idx_map = {n: i for i, n in enumerate(cols)} p1_nodes_order = [idx_map[n] for n in ind1.topology] p2_nodes_order = [idx_map[n] for n in ind2.topology] # for actual crossover operation DEAPs ordered crossover function is used ch1_node_order, ch2_node_order = tools.cxOrdered(p1_nodes_order, p2_nodes_order) # update the topology list on the resulting offsprings ind1.topology = [cols[i] for i in ch1_node_order] ind2.topology = [cols[i] for i in ch2_node_order] return ind1, ind2
def crossover(ind1, ind2, alpha): for i, (x1, x2) in enumerate(zip(ind1[0], ind2[0])): gamma = abs((1. + 2 * alpha) * random.random() - alpha) if gamma > 1.: gamma = gamma - 1 ind1[0][i] = int(math.floor((1. - gamma) * x1 + gamma * x2)) ind2[0][i] = int(math.floor(gamma * x1 + (1. - gamma) * x2)) ind1[1], ind2[1] = tools.cxOrdered(ind1[1], ind2[1]) pos = int(math.floor(len(ind1[2]) * random.random())) for i, (x1, x2) in enumerate(zip(ind1[2], ind2[2])): if i <= pos: a = ind2[2][i] ind2[2][i] = ind1[2][i] ind1[2][i] = a return ind1, ind2
def crossover(ind1, ind2, alpha): for i, (x1, x2) in enumerate(zip(ind1[0], ind2[0])): gamma = abs((1.0 + 2 * alpha) * random.random() - alpha) if gamma > 1.0: gamma = gamma - 1 ind1[0][i] = int(math.floor((1.0 - gamma) * x1 + gamma * x2)) ind2[0][i] = int(math.floor(gamma * x1 + (1.0 - gamma) * x2)) ind1[1], ind2[1] = tools.cxOrdered(ind1[1], ind2[1]) pos = int(math.floor(len(ind1[2]) * random.random())) for i, (x1, x2) in enumerate(zip(ind1[2], ind2[2])): if i <= pos: a = ind2[2][i] ind2[2][i] = ind1[2][i] ind1[2][i] = a return ind1, ind2
def orderCX(parent1, parent2): # convert list of cities' coords into indexes def ind_indices(individual): indices = [] for gene in individual: indices.append(cities_coords.index(gene)) return indices # convet list of indexes into cities' coords def ind_coords(individual): coords = [] for gene in individual: coords.append(cities_coords[gene]) return coords p1_indices = ind_indices(parent1) p2_indices = ind_indices(parent2) c1_indices, c2_indices = tools.cxOrdered(p1_indices, p2_indices) c1 = ind_coords(c1_indices) c2 = ind_coords(c2_indices) return c1, c2
res.append(individual) if len(res) >= amount // 2: break for i in range(amount - len(res)): res.append( min(random.choices(population, k=3), key=lambda x: x.fitness)) return res if __name__ == "__main__": population = generate_population() for _ in tqdm(range(GENERATIONS)): # Crossover for p1, p2 in itertools.product(population, population): if random.random() < CX_THRESHOLD: c1, c2 = cxOrdered(p1, p2) population.append(c1) population.append(c2) # Mutation for p in population: if random.random() < MUT_THRESHOLD: mutate(p) # Evaluate for p in population: p.fitness = evaluate(p) best = min(population, key=lambda x: x.fitness) if best.fitness == 0: break
if i < a or i > b: holes1[ind2[i]] = False holes2[ind1[i]] = False # We must keep the original values somewhere before scrambling everything temp1, temp2 = ind1, ind2 k1, k2 = b + 1, b + 1 for i in range(size): if not holes1[temp1[(i + b + 1) % size]]: ind1[k1 % size] = temp1[(i + b + 1) % size] k1 += 1 if not holes2[temp2[(i + b + 1) % size]]: ind2[k2 % size] = temp2[(i + b + 1) % size] k2 += 1 # Swap the content between a and b (included) for i in range(a, b + 1): ind1[i], ind2[i] = ind2[i], ind1[i] return ind1, ind2 # def mpda_PMX(): # pass if __name__ == '__main__': ind1 = [0, 1, 2, 3, 4] ind2 = [4, 3, 2, 1, 0] print(tools.cxOrdered(ind1, ind2))
from deap import tools random.seed(0) x = random.sample(range(10), 10) print(x) print(tools.mutShuffleIndexes(x, 1)) print(x) ind1 = random.sample(range(10), 10) ind2 = random.sample(range(10), 10) tools.cxTwoPoint(ind1, ind2) ind = [ind1, ind2] tools.cxOrdered(ind1, ind2) for i in range(100): ind1 = random.sample(range(10), 10) ind2 = random.sample(range(10), 10) tools.mutShuffleIndexes(ind1, 1) print(ind1) for i in range(100): ind1 = random.sample(range(10), 10) tools.mutUniformInt(ind1, 20, 100, 1) print(ind1) for i in range(100): ind1 = random.sample(range(100), 10) ind2 = random.sample(range(100), 10)