如何随机改变二进制列表中的5个值?

问题描述 投票:3回答:3

我正在编写一种遗传算法,其中我需要从二进制列表genotype中选择5个数字并将其翻转,因此1001。我尝试将代码与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

python random genetic-algorithm
3个回答
4
投票

您可以使用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]

1
投票

random.choice(genotype)将返回随机元素from基因型列表,即它将等于0或1。因此,由于您使用gene作为索引,因此您的函数将始终翻转一个元素在索引0或索引1处。

您可以改用random.sample(population, k)功能。


1
投票

而-random.sample(population, k)给出的答案是类似的

ilyankou

-您的主要问题的解决方案现在看起来很清楚,我发现了您的发现

我尝试将我的代码放入带有range(1,6)的循环中,但是当我这样做时,它仍然只更改其中一个数字。

乍看之下

颇具挑战性。这始终是真的吗?可以还是必须?

我尝试了以下代码的几次运行(我从原始代码中删除了多余的for i in random.sample(range(len(genotype)), 5): genotype[i] ^= 1

self

并且仅观察到这些输出:

  1. [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处的基因被翻转
  2. [[0, 0, 0, 1, 0, 0, 1, 1, 1, 0]-索引1的基因被翻转

事实上,对于上述[1, 1, 0, 1, 0, 0, 1, 1, 1, 0]函数的奇数次呼叫,实际上是这样的[[必须是:

因为mutategene0之一,并且同一基因上的两次翻转会重现初始值,所以只有与对应于奇数次选择的基因索引的突变相对应,并且由于您调用对于1(总数为奇数),在整个过程中,只有range(1, 6)0之一可以为奇数。
© www.soinside.com 2019 - 2024. All rights reserved.