文章目录
问题描述部分匹配交叉步骤(单点交叉为例)代码运行结果同理我们可以写出两点交叉变异的修订
问题描述
在进化算法的交叉环节中,无论是一点交叉还是两点交叉,基因重组后产生的后代可能出现编码重复的情况,那么就需要我们对产生的子代进行修订,常见修订算法有部分匹配交叉(PMX),顺序交叉(OX),循环交叉(CX)等
部分匹配交叉步骤(单点交叉为例)
step1: 确定初始种群 list1: [9, 3, 5, 4, 6, 0, 2, 1, 7, 8] list2: [1, 4, 0, 2, 7, 8, 6, 9, 5, 3]
step2: 随机产生小于父代向量长度的数,如y=2 [9, 3] [5, 4, 6, 0, 2, 1, 7, 8] [1, 4] [0, 2, 7, 8, 6, 9, 5, 3]
step3: 互换交换片段 [9, 3] [0, 2, 7, 8, 6, 9, 5, 3] [1, 4] [5, 4, 6, 0, 2, 1, 7, 8]
step4: 修订 保持被交换的片段不动,在没有交换的片段中寻找重复值,然后在父代被换走的部分中找到对应位置的元素进行替换。 说起来比较模糊,举例说明 本例中[9,3]均与换过来的[0, 2, 7, 8, 6, 9, 5, 3]有重复元素。 我们找到[5, 4, 6, 0, 2, 1, 7, 8]中与9,3对应位置的元素,然后[9,3]中的元素对应替换 第一次交换后的片段由[9, 3]变为了[1, 8]。但是8也与交叉片段重复,依次执行本操作,将8->0,继续查重,发现还重复,然后0->5->7->6->2->4 最终的片段为[1, 4] 相同原理对第二个子染色体进行修订 最终的染色体为 [1, 4, 0, 2, 7, 8, 6, 9, 5, 3] [9, 3, 5, 4, 6, 0, 2, 1, 7, 8]
代码
import random
import copy
a1
= random
.sample
(range(10), 10)
a2
= random
.sample
(range(10), 10)
a1_1
= copy
.deepcopy
(a1
)
a2_1
= copy
.deepcopy
(a2
)
print('初始种群为:\n', a1_1
, '\n', a2_1
)
y
= random
.randint
(0,len(a1_1
))
fragment1
= a1
[y
:]
fragment2
= a2
[y
:]
print('--' * 20, '\n单点交叉交换元素为:\n{}{}\n{}{}'.format(a1_1
[:y
], fragment1
, a2_1
[:y
], fragment2
))
a1_1
[y
:], a2_1
[y
:] = a2_1
[y
:], a1_1
[y
:]
print('--' * 20, '\n{}位置以后元素实现单点交叉:\n{}{}\n{}{}'.format(y
- 1, a1_1
[:y
], fragment2
, a2_1
[:y
], fragment1
))
a1_2
= []
a2_2
= []
for i
in a1_1
[:y
]:
while i
in fragment2
:
i
= fragment1
[fragment2
.index
(i
)]
a1_2
.append
(i
)
for i
in a2_1
[:y
]:
while i
in fragment1
:
i
= fragment2
[fragment1
.index
(i
)]
a2_2
.append
(i
)
child1
= a1_2
+ fragment2
child2
= a2_2
+ fragment1
print('--' * 20)
print('修正后的子代为:\n{}\n{}'.format(child1
, child2
))
运行结果
同理我们可以写出两点交叉变异的修订
import random
import copy
def two_points_cross(a1
,a2
):
a1_1
= copy
.deepcopy
(a1
)
a2_1
= copy
.deepcopy
(a2
)
point1
= random
.randint
(0, len(a1_1
))
point2
= random
.randint
(0., len(a1_1
))
while point1
> point2
or point1
== point2
:
point1
= random
.randint
(0, len(a1_1
))
point2
= random
.randint
(0., len(a1_1
))
fragment1
= a1
[point1
:point2
]
fragment2
= a2
[point1
:point2
]
a1_1
[point1
:point2
], a2_1
[point1
:point2
] = a2_1
[point1
:point2
], a1_1
[point1
:point2
]
a1_2
= []
a2_2
= []
a1_3
= []
a2_3
= []
for i
in a1_1
[:point1
]:
while i
in fragment2
:
i
= fragment1
[fragment2
.index
(i
)]
a1_2
.append
(i
)
for i
in a1_1
[point2
:]:
while i
in fragment2
:
i
= fragment1
[fragment2
.index
(i
)]
a1_3
.append
(i
)
for i
in a2_1
[:point1
]:
while i
in fragment1
:
i
= fragment2
[fragment1
.index
(i
)]
a2_2
.append
(i
)
for i
in a2_1
[point2
:]:
while i
in fragment1
:
i
= fragment2
[fragment1
.index
(i
)]
a2_3
.append
(i
)
child1
= a1_2
+ fragment2
+ a1_3
child2
= a2_2
+ fragment1
+ a2_3
return child1
,child2