Files
GeneticAlgorithm/GeneticAlgorithm.py
T
jens 358f6777e5 - initial import
git-svn-id: http://moon:8086/svn/projects/GeneticAlgorithm@237 fda53097-d464-4ada-af97-ba876c37ca34
2019-04-12 15:15:51 +00:00

169 lines
3.5 KiB
Python

import numpy as np
class FinessEvaluator(object):
def __init__(self):
self.x = np.linspace(-10,10,21)
pass
def process(self, c):
mse = 0
for x in self.x:
y = c.process(x)
mse += (y - self.fx(x))**2
mse *= 1/len(self.x)
fit = 1/(1 + mse)
return fit
def fx(self, x):
y = 5 + 3 * x + 7 * x**2
return y
class Cromosome(object):
def __init__(self, id, param=None):
self.id = id
self.fit = 0
self.fitAccum = 0
self.param = param
def process(self, x):
result = self.param[0] + self.param[1]*x + self.param[2]*x**2
return result[0]
def cross(self, p2):
a = 0.5
param1 = (1-a)*self.param + a*p2.param
param2 = (1-a)*p2.param + a*self.param
ca = Cromosome(self.id, param1)
cb = Cromosome(p2.id, param2)
return ca, cb
def mutate(self):
gene = int(np.random.rand() * 3)
allele = int(5*(0.5 - np.random.rand()))
self.param[gene] += allele
def __str__(self):
return "Id: {}, f={:0.6f}, fitAccum={:0.6f}, param=\n{}".format(self.id, self.fitness, self.fitAccum, str(self.param))
class Population(object):
def __init__(self, numCromosomes):
self.bestFit = 0
self.sumFit = 0
self.cromosomes = []
for i in range(0, numCromosomes):
self.cromosomes.append(Cromosome(str(i), np.random.rand(3,1)))
def print(self):
print ("Population fitness = {:0.6f}".format(self.sumFit))
print ("Best indiv. fitness = {:0.6f}".format(self.bestFit))
def process(self):
for c in self.cromosomes:
y = c.process(1)
return
def fitness(self, fitnessEval):
self.sumFit = 0
self.bestFit = 0
for c in self.cromosomes:
f = fitnessEval.process(c)
c.fitness = f
self.sumFit += f
if f > self.bestFit:
self.bestFit = f
# 1.) Sort by fitness
sorted = self.sort(self.cromosomes)
# 2.) Assign accumulated fitness
sum = 0
for c in sorted:
sum += c.fitness
c.fitAccum = sum
self.cromosomes = sorted
return self.sumFit
def mate(self, chanceOfReproduction=0.3):
newPop = self.cromosomes
count = 0
for i in range(0, int(len(self.cromosomes)/2)):
p = np.random.rand()
if p < chanceOfReproduction:
# 3.) Select parents
p1 = self.select(self.cromosomes)
p2 = p1
while(p2 == p1):
p2 = self.select(self.cromosomes)
ca, cb = p1.cross(p2)
newPop[count+0] = ca
newPop[count+1] = cb
count += 2
self.cromosomes = newPop
return newPop
def select(self, sorted):
p = self.sumFit * np.random.rand()
for c in sorted:
if c.fitAccum > p:
break
return c
def mutate(self, chanceOfMutation=0.06):
for c in self.cromosomes:
p = np.random.rand()
if p < chanceOfMutation:
c.mutate()
pass
def best(self):
return self.cromosomes[len(self.cromosomes)-1]
def starve(self):
pass
def sort(self, array):
less = []
equal = []
greater = []
if len(array) > 1:
pivot = array[0].fitness
for x in array:
if x.fitness < pivot:
less.append(x)
elif x.fitness == pivot:
equal.append(x)
elif x.fitness > pivot:
greater.append(x)
# Don't forget to return something!
return self.sort(less)+equal+self.sort(greater) # Just use the + operator to join lists
# Note that you want equal ^^^^^ not pivot
else: # You need to hande the part at the end of the recursion - when you only have one element in your array, just return the array.
return array
if __name__ == '__main__':
f = FinessEvaluator()
p = Population(50)
for i in range(0, 500):
p.mutate(0.1)
p.fitness(f)
p.mate()
p.print()
p.fitness(f)
p.print()
print(p.best())
print ("End of Program")