 # Genetic Algorithms in Python: Help me flip a random bit in a list. SOLVED

I have a list of randomly generated 0’s and 1’s. I need to pick a single bit and flip it to its opposite: either a zero to a one or a one to a zero. This is part of a genetic algorithm problem in Python.

What I have tried:

``````
import random as randint

pop_size = int(input('Enter a population size:'))
length = int(input('Enter an organism length:'))

orgs = []
for i in range(pop_size):
org = []
for a in range(length):
org.append(randint.randint(0,1))
orgs.append(org)

orgs.sort(reverse=True)
print orgs

new_orgs = []
new_org = orgs[0:(pop_size/2):1]
#look at user input for 50 or 25, etc
new_orgs.append(new_org)
print new_orgs

import random as randint
x = randint.choice(new_orgs)
j = randint.randrange(len(x))
x[j] = int(not x[j])
print x

``````

The code above returns this:

``````Enter a population size: 4
Enter an organism length: 3
[[1, 1, 1], [1, 0, 1], [1, 0, 0], [0, 1, 1]] #sorted list by sum
[[[1, 1, 1], [1, 0, 1]]] # half of list which has 'higher' fitness
[[1, 1, 1], 0] #output
``````

I need to get something like this:
`[[1, 0, 1], [1,1,1,]] #in regards to output`

I do not understand why the name change is necessary. Why not just,

``````import random
``````

?

1 Like
``````import random
x = random.choice(new_orgs)
j = random.randrange(len(x))
x[j] = int(not x[j])
print x
``````

Still returns:

``````Enter a population size: 4
Enter an organism length: 2
[[1, 0], [1, 0], [0, 1], [0, 1]]
[[[1, 0], [1, 0]]]
[[1, 0], 0]
``````
``````>>> import random
>>> orgs = [[1, 1, 1], [1, 0, 1], [1, 0, 0], [0, 1, 1]]
>>> x = random.choice(orgs)
>>> x
[1, 1, 1]
>>> j = random.randrange(len(x))
>>> j
0
>>> x[j] = int(not x[j])
>>> x
[0, 1, 1]
>>>
``````

Not sure why your output is different from the above.

1 Like

You specified the lists org, but I need it to be user input, not specified directly in the code

That was just for testing directly in the interactive console.

1 Like
``````import random as randint

pop_size = int(input('Enter a population size:'))
length = int(input('Enter an organism length:'))

orgs = []
for i in range(pop_size):
org = []
for a in range(length):
org.append(randint.randint(0,1))
orgs.append(org)

orgs.sort(reverse=True)
print orgs

new_orgs = []
new_org = orgs[0:(pop_size/2):1]
#look at user input for 50 or 25, etc
new_orgs.append(new_org)
print new_orgs

import random
x = random.choice(orgs)
j = random.randrange(len(x))
x[j] = int(not x[j])
print x
``````

returns:

``````Enter a population size: 4
Enter an organism length: 2
[[1, 1], [1, 1], [0, 0], [0, 0]]
[[[1, 1], [1, 1]]]
[1, 1, 0]
``````

I believe you want to operate on `new_orgs`. My test was generic and I called the list `orgs` arbitrarily. Don’t read anything into it.

2 Likes

The code I have above doesn’t look at orgs, but still returns the incorrect output.

Hi @captainap,

Does the code below reflect what you are trying to do? I assumed you wanted to mutate an individual within `orgs`, based on this statement …

``````x = random.choice(orgs)
``````

Should it be within `new_orgs`, instead? If so, that is easily fixed.

The organisms and locations within organisms are numbered starting at `0`, here. The following code was executed in Python 3.

``````import random

pop_size = int(input('Enter a population size:'))
length = int(input('Enter an organism length:'))

orgs = []
for i in range(pop_size):
org = []
for a in range(length):
org.append(random.randint(0,1))
orgs.append(org)

orgs.sort(reverse=True)
print(orgs)

new_orgs = []
new_org = orgs[0:(pop_size//2):1]
#look at user input for 50 or 25, etc
new_orgs.append(new_org)
print(new_orgs)

x = random.randint(0,len(orgs) - 1)
j = random.randint(0,len(orgs[x]) - 1)
orgs[x][j] = int(not orgs[x][j])
print("Mutation at organism {:d} location {:d}".format(x, j))
print(orgs[x])
``````
1 Like

Here is my final code:

``````import random
pop_size = int(input('Enter an even population size:'))
length = int(input('Enter an organism length:'))

orgs = []
for i in range(pop_size):
org = []
for a in range(length):
org.append(random.randint(0,1))
orgs.append(org)

print orgs
print "created pop"
orgs.sort(reverse=True)

fit = sum(org)
for fit in org:
print fit
print 'hello'
print orgs

print "sorted pop"
new_orgs = orgs[0:(pop_size//2)]
print new_orgs
print "best pop"

for some_org in new_orgs:
bit_to_flip = random.randrange(len(some_org))
if some_org[bit_to_flip] == 1:
some_org[bit_to_flip] = 0
else:
some_org[bit_to_flip] = 1
print new_orgs
print "mutated pop"
``````

Returns this:

``````Enter an even population size: 4
Enter an organism length: 2
[[0, 0], [1, 0], [0, 0], [0, 1]]
created pop
0
hello
1
hello
[[0, 1], [1, 0], [0, 0], [0, 0]]
sorted pop
[[0, 1], [1, 0]]
best pop
[[1, 1], [0, 0]]
mutated pop
``````

Yes, I know this code can be simplified. I’m still in the debugging stage and have a few more things to add. The prints are just there to guide me. What I’m working on next is creating a dictionary with organism as a key and fitness as a value. Then I should be able to take half of that dictionary and use it to sort. I also want to add in some user input: instead of half the population maybe I can get ten or twenty five percent. I’m also working on getting only an even number that the user inputs, which I believe can be solved with a While loop… And lastly, I have to create offspring and mutate them again and again!

…I love this project… 1 Like