-1

I am having problems with my for loops. moreover with multiple for loops, I don't seem to understand how they work.

herunder is my double for loop i want to implement in a genetic algorithm. The input of the code: population is an arraylist such as the mating_pool:

mating_pool = [[1,4,7,2,8,2],[3,5,6,8,5,4]]

r_mutation is the rate of mutation of a single element, anywhere in the population. i.e. the chance that a single element mutates.

def mutation(population,r_mutation):
    mut_pop = population
    for _i in range(len(population)):
        for _j in range(len(population[_i])):
            _ = random.randint(0,100)
            if _ < 100*r_mutation:
                mut_pop[_i][_j]    = random.randint(0,20)
    return mut_pop

r_mutation = 0.80
mutated_pop = mutation(mating_pool, r_mutation)

In my case, even with high r_mutation, mutated_pop equals mating_pool at every point. I want the integers in the population to mutate with a chance of 80%. How can I solve this?

Dhuijsman
  • 51
  • 4
  • "pops out as the same as the input" - it doesn't. I ran this twice and got `[[1, 4, 7, 10, 8, 2], [3, 5, 6, 8, 5, 4]]` and `[[1, 4, 7, 10, 8, 1], [3, 11, 19, 8, 5, 19]]`. Your code has randomness, but no change is a valid outcome. – ForceBru Apr 01 '22 at 16:00
  • 1
    I mean, sure, `mutated_pop == mating_pool` because you're modifying `mating_pool` in-place – ForceBru Apr 01 '22 at 16:01
  • 1
    BTW, the correct term is ***nested** loop*. – PM 77-1 Apr 01 '22 at 16:02
  • 1
    How many times did you try it? There's almost a 7% chance of no mutations occurring on a given run. – jasonharper Apr 01 '22 at 16:02
  • Hey, thank you for your fast replies. I have the code running on pupulation of 15x48. with an r_mutation of over 0.90, and the output is the same as the input – Dhuijsman Apr 01 '22 at 16:05
  • How do *you* know that the output is the same as the input? – quamrana Apr 01 '22 at 16:07
  • I have updated the question slightly to better reflect the problem. my mut_pop is the same as population every single run of the algorithm. – Dhuijsman Apr 01 '22 at 16:21
  • @ForceBru I have changed the code to be not in-place. my outputs, however are still the same.. – Dhuijsman Apr 01 '22 at 16:24
  • 1
    Your example code still mutates the original lists and still works as expected. Your problem is not reproducible. – Michael Szczesny Apr 01 '22 at 16:25
  • @MichaelSzczesny thank you for your reply. How can I keep the original list unaltered? I.e. create a new list? I expected it to keep population the same because I transferred it to mut_pop before the coding – Dhuijsman Apr 01 '22 at 16:30
  • 2
    Please make shure the [mre] matches the problem. Does this help? [How to deep copy a list?](https://stackoverflow.com/q/17873384/14277722). – Michael Szczesny Apr 01 '22 at 16:35

1 Answers1

0
_ = random.randint(0,100)
if _ < 100*r_mutation:
    population[_i][_j]    = random.randint(0,20)

So, _ is a random number between 0 and 100, right?. And then you mutate a element if... the random number is lower than 100.

Given that you have a random number between 0 and 100, I'd say that there's a 20% chance that the number is lower than 20, wouldn't you? So replacing the mutation with

    if _ > 20
        population[_i][_j] = new_mutated_value
Cabanur
  • 18
  • 3
  • "you mutate a element if... the random number is lower than 100" - OP's code defines `r_mutation = 0.80`, so the element is mutated if `_ < 100 * 0.8`, so is the random number is lower than 80 which happens about 80% of the time, doesn't it? Basically, OP's code does the same thing as the `if _ > 20` example – ForceBru Apr 01 '22 at 16:52
  • yes, i believe this part is not really the problem. I think the code itself works, but it rewrites the original input `population` aswell as the `mutated_pop` im trying to find something for that but the arrays are a bit of a pain. – Dhuijsman Apr 01 '22 at 18:02