Reputation: 65
I recently saw a video on Youtube about genetic algorithms and thought it was quite interesting and decided to give it a go. Me, being new to programming and not having experience with any language other than Python, thought C#, which seemed to be the most widely used language for genetic algorithms, was t0o hard and decided to give it a try in Python. And I am currently stuck because of an error, and I can't quite figure out what is wrong with the code.
This is the code:
import random
#Wanted String
STRING_NAME = "this is a genetic algorithm"
LENG = len(STRING_NAME)
#Used Characters
VALID_CHARACTERS = "abcdefghijklmopqrstuvwxyz "
#Generation Size
POPULATION_SIZE = 200
#List of String Objects
POPULATION = []
closest = 100
choiceList = []
#Generating random strings
def randomStringGeneration(size=len(STRING_NAME)):
return ''.join(random.choice(VALID_CHARACTERS) for _ in range(size))
#string object
class ranString:
def __init__(self,manualstr=""):
if manualstr == "":
self.string = randomStringGeneration()
else:
self.string = manualstr
self.fitness = fitnessCheck(self)
#fitness checking
def fitnessCheck(String):
result = 0;
for x in range(0,LENG-1):
if (String.string[x] == STRING_NAME[x]):
result += 1
return result
#order population list by fitness decrementaly
def sortByFitness(Obj):
Obj.sort(key=lambda x: x.fitness, reverse=True)
#mating two strings
def mate(x,y):
tempxstr = x.string
tempystr = y.string
child1 = tempxstr[0:10]+tempystr[14:20]+tempxstr[21:26]
child2 = tempystr[0:10]+tempxstr[14:20]+tempystr[21:26]
ranchild1 = ranString(manualstr = child1)
ranchild2 = ranString(manualstr = child2)
POPULATION.append(child1,child2)
#main function
def generatePopulation(num):
generation = 1
for x in range(num):
if (generation == 1):
for x in range(POPULATION_SIZE):
f = ranString()
POPULATION.append(f)
sortByFitness(POPULATION)
for x in POPULATION:
print(x.string + " " + str(x.fitness))
generation +=1
else:
sortByFitness(POPULATION)
del POPULATION[100:]
for x in POPULATION:
for j in range(x.fitness):
choiceList.append(x)
for j in range(100):
x = random.choice(choiceList)
y = random.choice(choiceList)
mate(x,y)
print("\n\n\n\nGeneration"+generation)
for x in POPULATION:
print(x.string + " " + str(x.fitness))
generation += 1
generatePopulation(10)
This is the log(do you call these log files?) file with the error:
egf ukcob uf oyhtuikmdritiz 4
ouaelyf ef wufsjh aqkcyacef 3
rbuwptsdjmwskfzyccsfgzlwdyo 3
fqyg zhhhswesdfetqjy ohrpyj 3
qfirzajzhafdv dicmueavdrguv 3
pxqsxtehe bckbvadapezgrqdkb 3
zvosvvsspgbpmxhadwxkfzkqjhi 3
tfsofiurlpyakhhwqqexoafhtxi 3
qkmslihwskukcecldykkp caiqo 3
fhfh ctluzbr vty skgozgqclg 3
dglsfwimwqfxdhdzx lkcvrraev 3
jbuwaoxua uteissqfpxodciaoa 3
if qpvpcsixe kagmxyludcicwl 3
vspwdxwqkewcaethcs g dxcxao 3
d jpylld gzuojvccuh gzjxbs 3
pvzsjkxtzrjgjegimalvcaxjbjw 3
zolqfli sdahohjiryerabkvmme 2
ufslbdexaa wrfuscfbkfdulzfr 2
*
* (middle part omitted because it would be too long)
*
jcjigwzhyxwwyikfoiyrtolclg 0
srjqfxjbuppfd drlrkjkuqegvb 0
zbsbkedazmxyghrmhzdzjytcqza 0
xqxmtxrkhctqayrmkvefkpy zad 0
waxpeefkvqjjwvylre jfvedyfa 0
udyetsjd lmhuzamrwt rip dqv 0
Traceback (most recent call last):
File "/Users/Johnwon/Desktop/Genetic String.py", line 80, in <module>
generatePopulation(10)
File "/Users/Johnwon/Desktop/Genetic String.py", line 73, in generatePopulation
mate(x,y)
File "/Users/Johnwon/Desktop/Genetic String.py", line 48, in mate
ranchild1 = ranString(manualstr = child1)
File "/Users/Johnwon/Desktop/Genetic String.py", line 28, in __init__
self.fitness = fitnessCheck(self)
File "/Users/Johnwon/Desktop/Genetic String.py", line 34, in fitnessCheck
if (String.string[x] == STRING_NAME[x]):
IndexError: string index out of range
I've searched the Internet for the out of index error and it seems that I incremented too much or searched for an index that is not existent but I can't find the cause for the error. What is wrong with my code?
Also, currently my mate() function works by adding the strings to a separate list multiplied by their fitness then randomly selecting 2 of them and swapping a third of their 'genes' and popping out 2 babies. This is the only way I could think of to give more fit objects a higher chance to mate but this seems horribly unoptimized as the generations go and fitness levels grow higher. What could be a good way to do this and implement mutation?
I'm a beginner in Python and I'm open to any opinions on how to improve my code. Thanks for reading!
Upvotes: 0
Views: 76
Reputation: 76244
child1 = tempxstr[0:10]+tempystr[14:20]+tempxstr[21:26]
child2 = tempystr[0:10]+tempxstr[14:20]+tempystr[21:26]
This doesn't look right to me. These strings will each have a length of 21. But inside fitnessCheck
, you're comparing them against STRING_NAME
, which has a length of 27. So once x
reaches 21 inside fitnessCheck
, you'll get an IndexError.
You should change how you create child1
and child2
so that they have the same length as STRING_NAME
.
Upvotes: 1