Search code examples
pythonrandomgenetic-algorithm

How to randomly mutate 5 values in a binary list?


I'm writing a genetic algorithm in which I need to select 5 numbers from the binary list genotype and flip them, so a 10 and 01. I tried putting my code in a loop with a range(1,6) however when I do this it still only changes one of the numbers. Below is my original code without the loop which randomly selects one of the binary values and mutates it. Does anyone know a better way of doing this but for 5 of the elements in the list?

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


Solution

  • While your primary problem seems solved after the answer given by ilyankou:

    for i in random.sample(range(len(genotype)), 5):
        genotype[i] ^= 1
    

    and this alternative (more realistic) mutation model was suggested:

    for i in [random.choice(range(len(genotype))) for _ in range(5)]:
        genotype[i] ^= 1
    

    I found this observation quite challenging and somewhat inspiring

    I tried putting my code in a loop with a range(1,6) however when I do this it still only changes one of the numbers.

    Is this this always true? Can it or must it be?

    I tried several runs of the following code (I removed the superfluous self from your original)

    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)
    

    and observed only these outputs:

    1. [0, 0, 0, 1, 0, 0, 1, 1, 1, 0] -- gene at index 0 flipped
    2. [1, 1, 0, 1, 0, 0, 1, 1, 1, 0] -- gene at index 1 flipped

    And indeed this has to be like this for an odd count of calls to the mutate function above:

    Because gene is one of 0 and 1 and double flips on the same gene reproduce the initial value, only mutations will remain that correspond to gene indices which are chosen an odd number of times, and since you call it for range(1, 6) (an odd total), only one of 0 and 1 can be of odd quantity in the overall process.