-
-
Save NicolleLouis/d4f88d5bd566298d4279bcb69934f51d to your computer and use it in GitHub Desktop.
| #!/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 |
I think
return nextPopulation
should be replaced by " return nextGeneration" in Line 88
You are both perfectly right, fixed those issues. Sorry :)
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
@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.
@danelee2601
It doesn't work.
for i in range(int(len(breeders)/2)): <--it works.
print time.time() - temps1 gives syntax error
divyagangadhar, if you're using python 3, try
print (time.time() - temps1)
that should fix it
hey, can you just help me by explaining the 2 output graphs. i.e., fitness best individual vs generation and average fitness vs generation
You have # !/usr/bin/python3.5 shebang and using python2 print statement..