The Advance Crossover in Genetic Algorithm

In the sequential encoding, some illegal descendants might be generated where the corresponding approaches such as refusal, punishment orrepair are required.

For example: After the crossover operator, the children’s encoding is out of expectation:

P1: 21|345|67  P2: 43|125|76

C1: 21|125|67  P2: 43|345|67

There are various kinds of techniques to fix the illegal situation:

1)     PartiallyMapped Crossover

Step 1: Select the proper splitting point X, Y

Step 2: Switch the middle part, and fix them

Step 3: Determine the map relationship

Step 4: Map the rest to the corresponding sequence based on the mapped relationship


import copy
import random
def partial_map(parent1, parent2, insert=None):
    chromosome_len = len(parent1)
    child1 = copy.deepcopy(parent1)
    child2 = copy.deepcopy(parent2)
    if insert is None:
        insert = random.sample(range(1, chromosome_len), 2)
    map_relation = map(lambda x, y: (x, y), child1[min(insert):max(insert)], child2[min(insert):max(insert)])
    for (key, item) in map_relation:
        child1[parent1.index(key)] = item
        child1[parent1.index(item)] = key
        child2[parent2.index(item)] = key
        child2[parent2.index(key)] = item
    return child1, child2

2)     Order Crossover

Step 1: Select the splitting point X, Y

Step 2: Switch the middle part and fix the pairs

Step 3: List the first genes behind the splittingpoint Y, and remove the fixed genes

Step 4: Generate the sequence from the first position behind the splitting point Y


This crossover can keep the adjacent relationship and precedence order, and meets the requirement of TSP, but neglects the bit feature.

import random
def order_crossover(parent1, parent2, insert=None):
    chromosome_len = len(parent1)
    if insert is None:
        insert = random.sample(range(1, chromosome_len), 2)
    # list all the genes in an original order
    gene_list1 = parent1[max(insert):] + parent1[:max(insert)]
    gene_list2 = parent2[max(insert):] + parent2[:max(insert)]
    fixed_part1 = parent1[min(insert):max(insert)]
    fixed_part2 = parent2[min(insert):max(insert)]
    filter_list1 = filter(lambda x: x not in fixed_part2, gene_list1)
    filter_list2 = filter(lambda x: x not in fixed_part1, gene_list2)
    child1 = filter_list1[-min(insert):] + fixed_part2 + filter_list1[:-min(insert)]
    child2 = filter_list2[-min(insert):] + fixed_part1 + filter_list2[:-min(insert)]
    return child1, child2

3)     Cycle Crossover

The basic idea is that the bit of the position should be the same as the parents.

Step 1: select the first element of P1 as the first bit of C1,

Select the first element of P2 as the first bit of C2

Step 2: Find the first element of P2 in P1 and assign the element to the relative position in C1. Repeat the process until the first element in P1 is found in P2, which is called a cycle.

Step 3: Continue to take turns to operate on the most fore genes in P1, P2. (In the first step the first bit will be assigned to C1 while the second step assigned to C2, and in the third step, the first bit will be assigned to C1 again)

Step 4: Repeat the above process until all the bits are completed


import numpy as np
def cycle_crossover(parent1, parent2):
    chromosome_len = len(parent1)
    child1 = np.zeros(chromosome_len, dtype=int)
    child2 = np.zeros(chromosome_len, dtype=int)
    rest_index = range(0, chromosome_len)
    index1 = []
    index2 = []
    indicator = 0
    while indicator < chromosome_len:
        if indicator % 2 == 0:
            start = rest_index[0]
            while start < chromosome_len:
                value = parent2[start]
                index1.append(start)
                if value == parent1[rest_index[0]]:
                    break
                start = parent1.index(value)
        rest_index = filter(lambda x: x not in index1, rest_index)

        if indicator % 2 == 1:
            start = rest_index[0]
            while start < chromosome_len:
                value = parent2[start]
                index2.append(start)
                if value == parent1[rest_index[0]]:
                    break
                start = parent1.index(value)
        rest_index = filter(lambda x: x not in index2, rest_index)
        if len(rest_index) == 0:
            break
        indicator += 1
    child1[index1] = np.array(parent1)[index1]
    child1[index2] = np.array(parent2)[index2]
    child2[index1] = np.array(parent2)[index1]
    child2[index2] = np.array(parent1)[index2]
    return child1.tolist(), child2.tolist()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值