0

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?

1 Answers1

1

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
Jeremy Savage
  • 944
  • 5
  • 14
  • 1
    Since I used a bitstring with `39 bits`, then a good default mutation rate would be `(1/39) = 0.025`. This mutation rate is turning on `4bits`. However, I need to keep on three bits only. It is a must thing. Can you make a more generalized way to flip the bits from the `Candidate solution` `(111000000000000000000000000000000000000)` to a `New Candidate solution` `(110000010000000000000000000000000000000)`? Can we do something like this? –  Oct 05 '22 at 22:22
  • @Jeremy I think this solution will exceed 3-bits on condition. In the question, it is mentioned to keep 3 bits since #Adil Abid has 3 ambulances only. – ExploringAI Oct 05 '22 at 22:28
  • @AdilAbid, please see the updated answer - should return only 3 bits now. – Jeremy Savage Oct 05 '22 at 22:45
  • @JeremySavage Yes. It works now. Sometimes, it is returning 2bits on, but I think it is ok since I can put a check to count 1's in the string. Thanks a ton –  Oct 05 '22 at 22:57
  • @JeremySavage Is it possible to flip a bit of our own choice? For example, keeping 2 bits in the original position and randomly changing another one since we want to make a control mutation and the change should be small. Like from (111000000000000000000000000000000000000) to (011100000000000000000000000000000000000). This is a small change according to the problem scenario. I can post another question if it sounds ok. – ExploringAI Oct 06 '22 at 11:12
  • @LearningLogic I missed a condition - see updated answer which should always return 3 bits, no more, no less. – Jeremy Savage Oct 06 '22 at 12:30
  • @ExploringAI do you mean you choose the bit? Or it flips at *most* one bit? – Jeremy Savage Oct 06 '22 at 12:30
  • @JeremySavage I mean I want to keep the positions of 2 bits as it is and want to change the 3rd bit in nearby positions. This will help me to achieve a small change. Like mentioned in my comment the original candidate solution is (111000000000000000000000000000000000000). Here, for instance, I want to keep 2 bits' position and randomly change the 3rd one. It will become (011100000000000000000000000000000000000). As you can see, the bit on 2nd, 3rd positions are not changed and are kept as it is in the original candidate solution. However, I changed the bit on the first position. – ExploringAI Oct 06 '22 at 12:59
  • @JeremySavage I have posted my question. See https://stackoverflow.com/questions/73973590/controlling-mutation-in-39bit-string-as-a-candidate-solution-in-genetic-algorith – ExploringAI Oct 06 '22 at 12:59
  • @JeremySavage Thanks. What value are you passing as a mutation rate (mr: float). –  Oct 06 '22 at 13:02
  • @LearningLogic I was using 0.05 as a test value to test the function. However, you should probably use a lower value than this, although I cannot say exactly what as there is no *correct* answer. If you choose a value too high your mutations will happen too often and you will effectively be performing a random search. Too low and your solution will get stuck in a non-optimal local minima solution as opposed to a more correct global minima solution. – Jeremy Savage Oct 06 '22 at 13:39
  • @JeremySavage I agree with you. Presently, I am working on a fitness function to see how it goes. If possible, can you comment on your code? I am trying to debug and make my own code to clear my concepts since I need to use it for an optimization problem. Can you comment the code, please? –  Oct 09 '22 at 16:12
  • Hi @JeremySavage This is working well with the situation stated in the question. Could you some add comments? –  Oct 14 '22 at 13:15