Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#!/usr/bin/python3.5
# -*-coding:Utf-8 -*
import random
import operator
import time
import matplotlib.pyplot as plt
temps1 = time.time()
#genetic algorithm function
def fitness (password, test_word):
score = 0
i = 0
while (i < len(password)):
if (password[i] == test_word[i]):
score+=1
i+=1
return score * 100 / len(password)
def generateAWord (length):
i = 0
result = ""
while i < length:
letter = chr(97 + int(26 * random.random()))
result += letter
i +=1
return result
def generateFirstPopulation(sizePopulation, password):
population = []
i = 0
while i < sizePopulation:
population.append(generateAWord(len(password)))
i+=1
return population
def computePerfPopulation(population, password):
populationPerf = {}
for individual in population:
populationPerf[individual] = fitness(password, individual)
return sorted(populationPerf.items(), key = operator.itemgetter(1), reverse=True)
def selectFromPopulation(populationSorted, best_sample, lucky_few):
nextGeneration = []
for i in range(best_sample):
nextGeneration.append(populationSorted[i][0])
for i in range(lucky_few):
nextGeneration.append(random.choice(populationSorted)[0])
random.shuffle(nextGeneration)
return nextGeneration
def createChild(individual1, individual2):
child = ""
for i in range(len(individual1)):
if (int(100 * random.random()) < 50):
child += individual1[i]
else:
child += individual2[i]
return child
def createChildren(breeders, number_of_child):
nextPopulation = []
for i in range(len(breeders)/2):
for j in range(number_of_child):
nextPopulation.append(createChild(breeders[i], breeders[len(breeders) -1 -i]))
return nextPopulation
def mutateWord(word):
index_modification = int(random.random() * len(word))
if (index_modification == 0):
word = chr(97 + int(26 * random.random())) + word[1:]
else:
word = word[:index_modification] + chr(97 + int(26 * random.random())) + word[index_modification+1:]
return word
def mutatePopulation(population, chance_of_mutation):
for i in range(len(population)):
if random.random() * 100 < chance_of_mutation:
population[i] = mutateWord(population[i])
return population
def nextGeneration (firstGeneration, password, best_sample, lucky_few, number_of_child, chance_of_mutation):
populationSorted = computePerfPopulation(firstGeneration, password)
nextBreeders = selectFromPopulation(populationSorted, best_sample, lucky_few)
nextPopulation = createChildren(nextBreeders, number_of_child)
nextGeneration = mutatePopulation(nextPopulation, chance_of_mutation)
return nextGeneration
def multipleGeneration(number_of_generation, password, size_population, best_sample, lucky_few, number_of_child, chance_of_mutation):
historic = []
historic.append(generateFirstPopulation(size_population, password))
for i in range (number_of_generation):
historic.append(nextGeneration(historic[i], password, best_sample, lucky_few, number_of_child, chance_of_mutation))
return historic
#print result:
def printSimpleResult(historic, password, number_of_generation): #bestSolution in historic. Caution not the last
result = getListBestIndividualFromHistorique(historic, password)[number_of_generation-1]
print ("solution: \"" + result[0] + "\" de fitness: " + str(result[1]))
#analysis tools
def getBestIndividualFromPopulation (population, password):
return computePerfPopulation(population, password)[0]
def getListBestIndividualFromHistorique (historic, password):
bestIndividuals = []
for population in historic:
bestIndividuals.append(getBestIndividualFromPopulation(population, password))
return bestIndividuals
#graph
def evolutionBestFitness(historic, password):
plt.axis([0,len(historic),0,105])
plt.title(password)
evolutionFitness = []
for population in historic:
evolutionFitness.append(getBestIndividualFromPopulation(population, password)[1])
plt.plot(evolutionFitness)
plt.ylabel('fitness best individual')
plt.xlabel('generation')
plt.show()
def evolutionAverageFitness(historic, password, size_population):
plt.axis([0,len(historic),0,105])
plt.title(password)
evolutionFitness = []
for population in historic:
populationPerf = computePerfPopulation(population, password)
averageFitness = 0
for individual in populationPerf:
averageFitness += individual[1]
evolutionFitness.append(averageFitness/size_population)
plt.plot(evolutionFitness)
plt.ylabel('Average fitness')
plt.xlabel('generation')
plt.show()
#variables
password = "banana"
size_population = 100
best_sample = 20
lucky_few = 20
number_of_child = 5
number_of_generation = 50
chance_of_mutation = 5
#program
if ((best_sample + lucky_few) / 2 * number_of_child != size_population):
print ("population size not stable")
else:
historic = multipleGeneration(number_of_generation, password, size_population, best_sample, lucky_few, number_of_child, chance_of_mutation)
printSimpleResult(historic, password, number_of_generation)
evolutionBestFitness(historic, password)
evolutionAverageFitness(historic, password, size_population)
print time.time() - temps1
@camabeh

This comment has been minimized.

Copy link

@camabeh camabeh commented Aug 30, 2017

You have # !/usr/bin/python3.5 shebang and using python2 print statement..

@ZR-Huang

This comment has been minimized.

Copy link

@ZR-Huang ZR-Huang commented Aug 31, 2017

I think

return nextPopulation

should be replaced by " return nextGeneration" in Line 88

@NicolleLouis

This comment has been minimized.

Copy link
Owner Author

@NicolleLouis NicolleLouis commented Sep 11, 2017

You are both perfectly right, fixed those issues. Sorry :)

@MarlieChiller

This comment has been minimized.

Copy link

@MarlieChiller MarlieChiller commented Nov 2, 2017

for i in int(range(len(breeders) / 2)):

(Line 70) produces this error:

TypeError: 'float' object cannot be interpreted as an integer - when you try and run it out of the box

@danelee2601

This comment has been minimized.

Copy link

@danelee2601 danelee2601 commented Dec 21, 2017

@MarlieChiller
For that issue, you simply need to change that "for i in int(range(len(breeders) / 2)):" to "for i in int(range(len(breeders) // 2)):" -> since range function itself cannot take float type, the error occurs. "//" operator leaves only quotients, dropping remainders.

I've tried it and the code worked. I hope it will be helpful.

@Astmara

This comment has been minimized.

Copy link

@Astmara Astmara commented Jan 4, 2018

@danelee2601
It doesn't work.

for i in range(int(len(breeders)/2)): <--it works.

@divyagangadhar

This comment has been minimized.

Copy link

@divyagangadhar divyagangadhar commented May 4, 2018

print time.time() - temps1 gives syntax error

@Jens1989

This comment has been minimized.

Copy link

@Jens1989 Jens1989 commented May 8, 2018

divyagangadhar, if you're using python 3, try

print (time.time() - temps1)

that should fix it

@divyagangadhar

This comment has been minimized.

Copy link

@divyagangadhar divyagangadhar commented May 10, 2018

hey, can you just help me by explaining the 2 output graphs. i.e., fitness best individual vs generation and average fitness vs generation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.