pythonbit-manipulationgenetic-algorithmmutationcrossover

Mutation with String Encoded Chromosomes - Genetic Algorithm


I am implementing Genetic Algorithm (GA). There are 43 numbers [Ambulance Locations] to choose from (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39) , I choose 3 places since I have 3 ambulances.

I can only put my ambulance in 3 locations among 1-39 locations (Restriction).

A chromosome sample: [000010000000000000100000000000100000000]. This represents that I want to put my Ambulance on the 5th, 19th, and 31 positions. The bits against positions 5th, 19th, and 31 are 1 and rest positions are 0. In other words, I am turning on 5-bit, 19-bit, and 31-bit.

Let's say, I have a Chromosome as:

Candidate solution 1 (111000000000000000000000000000000000000) 

My candidate solution is encoded in 39-bits,I want to do a mutation on these 39-bits to search for more combinations in my search space.

What can be a good approach to perform mutation while placing ambulances in 3 locations among 1-39 locations?


Solution

  • To mutate a genetic algorithm you will want to go through each bit in your solution and flip it based on a mutation rate - mr.

    For each bit gene, loop through and use the chance of it being flipped (from 0 -> 1 or from 1 -> 0) to mutate the final output.

    import random
    
    def mutate(input: str, mr: float) -> str:
        number_of_mutations = [index for index, gene in enumerate(input) if gene == "1"]
        mr = mr/len(number_of_mutations)
        for i in number_of_mutations:
            output = ""
            mutated = False
            for gene in input:
                if random.random() < mr and not mutated and gene != "1":
                    # quick way of flipping bit 0 -> 1 or 1 -> 0
                    output += str(1 - int(gene))
                    mutated = True
                else:
                    output += gene
            if mutated:
                if int(i) == 0:
                    output = "0" + output[1:]
                else:
                    output = output[:int(i)] + "0" + output[int(i)+1:]
            input = output
        return output