我正在编写一种遗传算法,其中我需要从二进制列表genotype
中选择5个数字并将其翻转,因此1
→0
和0
→1
。我尝试将代码与range(1,6)
放在一个循环中,但是当我这样做时,它仍然只更改其中一个数字。下面是我没有循环的原始代码,该循环随机选择二进制值之一并将其变异。除了列表中的5个元素之外,没有人知道更好的方法吗?
genotype = [1,0,0,1,0,0,1,1,1,0]
def mutate(self):
gene = random.choice(genotype)
if genotype[gene] == 1:
genotype[gene] = 0
else:
genotype[gene] = 1
return genotype
您可以使用random.sample()
函数从列表中获取5个唯一索引,然后将它们循环翻转。像这样:
import random
genotype = [1,0,0,1,0,0,1,1,1,0]
random_five = random.sample(range(len(genotype)), 5)
for i in random_five:
genotype[i] = 0 if genotype[i] == 1 else 1
print(genotype)
输出为:
[1, 1, 0, 1, 1, 0, 0, 1, 0, 1]
random.choice(genotype)
将返回随机元素from基因型列表,即它将等于0或1。因此,由于您使用gene
作为索引,因此您的函数将始终翻转一个元素在索引0或索引1处。
您可以改用random.sample(population, k)
功能。
而-random.sample(population, k)
给出的答案是类似的
ilyankou
-您的主要问题的解决方案现在看起来很清楚,我发现了您的发现
乍看之下我尝试将我的代码放入带有range(1,6)的循环中,但是当我这样做时,它仍然只更改其中一个数字。
颇具挑战性。这始终是真的吗?可以还是必须?
我尝试了以下代码的几次运行(我从原始代码中删除了多余的for i in random.sample(range(len(genotype)), 5):
genotype[i] ^= 1
)
self
并且仅观察到这些输出:
import random
genotype = [1,0,0,1,0,0,1,1,1,0]
def mutate():
gene = random.choice(genotype)
if genotype[gene] == 1:
genotype[gene] = 0
else:
genotype[gene] = 1
return genotype
print(genotype)
for _ in range(1,6):
mutate()
print(genotype)
-索引0处的基因被翻转[0, 0, 0, 1, 0, 0, 1, 1, 1, 0]
-索引1的基因被翻转事实上,对于上述[1, 1, 0, 1, 0, 0, 1, 1, 1, 0]
函数的奇数次呼叫,实际上是这样的[[必须是:
mutate
是gene
和0
之一,并且同一基因上的两次翻转会重现初始值,所以只有与对应于奇数次选择的基因索引的突变相对应,并且由于您调用对于1
(总数为奇数),在整个过程中,只有range(1, 6)
和0
之一可以为奇数。