Алгоритм кроссовера в моем GA отличается от того, что вы используете - не лучше, а просто другой. В сумме, вместо подстановки, я кодировал кроссовер как операцию объединения / объединения массивов , в которой точка сплайсинга рандомизирована (а также «синхронизирована», так что когда две сплайсированные части собранный дочерний вектор, который в результате имеет ту же длину, что и каждый родительский.
Я думаю, что это гораздо проще объяснить в коде:
DOMAIN_LENGTH = 14
def crossover(v1, v2):
crossover_point = random.randint(1, DOMAIN_LENGTH-2)
return v1[:crossover_point] + v2[crossover_point:]
# create a simple function to generate a couple of 'parent' vectors
>>> fnx = lambda v : [random.choice(range(10)) for c in range(DOMAIN_LENGTH)]
# now generate those parent vectors
>>> v1 = fnx(DOMAIN_LENGTH)
>>> v2 = fnx(DOMAIN_LENGTH)
>>> v1
[7, 9, 5, 6, 6, 7, 6, 9, 8, 6, 6, 4, 5, 8]
>>> v2
[2, 2, 9, 7, 1, 4, 6, 9, 0, 7, 1, 9, 3, 0]
>>> len(v1); len(v2)
14
14
# create the child vector via crossover
>>> child_01 = crossover(v1, v2)
>>> child_01
[7, 9, 9, 7, 1, 4, 6, 9, 0, 7, 1, 9, 3, 0]
>>> len(child_01)
14
так для:
- размер домена (длина вектора) 5
- a * crossover_point * из 2 и t
- два родительских вектора представляют собой [4, 3, 2, 4, 8] и [1, 3, 1, 6, 3]
, то:
# fragment contributed from first parent:
>>> f1 = p1[:2]
>>> f1
[4, 3]
# fragment contributed from second parent:
>>> f2 = p2[2:]
>>> f2
[1, 6, 3]
# now just concatenate the two fragments to produce the child fragment
>>> child = f1 + f2
>>> child
[4, 3, 1, 6, 3]
>>> len(child) == len(p2)
True