Search code examples
python-3.xmutation

Flipping bits in nested lists


I have a project wherein I have to use bit-flip mutation of genetic algorithm.

The code I have so far looks like this:

def mutation(pop, mr):
    for i in range(len(pop)):
        if (random.random() < mr):
            if (pop[i] == 1):
                pop[i] = 0
            else:
                pop[i] = 1
        else:
            pop[i] = pop[i]
    return pop

mut = mutation(populations, 0.3)
print(mut)

For example, I have the following (depending on my project, populations can look like populations_1 or populations_2):

populations_1 = [[1, 0], [1, 1], [0, 1], [1, 0]] 
populations_2 = [[1], [1], [0], [1]]

What I am doing is assigning random generated numbers to elements in populations and check if it is less than mutation rate. If it is, then bit-flip mutation will happen, if not, it will remain as it is. For the case of populations_1, if populations_1 index 2 is less than mutation rate, then it should become [1, 0]. For populations_2 index 3, it should become [0] if it is less than mutation rate. This is the objective of the mutation function.

Can anyone help me with turning the code I have so far to adapt situations like in populations_1? I think the code I have so far only works for populations_2.

Any help/suggestion/readings would be very much appreciated! Thanks!


Solution

  • You can use list comprehensions to do what you want. The values in pop are updated only if r<mr. To update them, you can iterate over each element (a) in list pop[i], and if a == 0 it becomes 1, otherwise 0. See the code below:

    def mutation(pop, mr):
        for i in range(len(pop)):
            r = random.random()
            print(r) # you can remove this line, it is only for testing
            if r < mr:
                pop[i] = [1 if a == 0  else 0 for a in pop[i]]
        return pop
    

    Test 1:

    populations_1 = [[1, 0], [1, 1], [0, 1], [1, 0], [0,0]] 
    mut = mutation(populations_1, 0.3)
    print(mut)
    
    #random number for each iteration
    0.3952226177233832
    0.11290933711515283
    0.08131952363738537
    0.8489702326753509
    0.9598842135077205
    #output:
    [[1, 0], [0, 0], [1, 0], [1, 0], [0, 0]]
    

    Test 2:

    populations_2 = [[1], [1], [0], [1]]
    mut = mutation(populations_2, 0.3)
    print(mut)
    
    
    0.3846024893833684
    0.7680389523799874
    0.19371896835988422
    0.008814288533701364
    [[1], [1], [1], [0]]