- initial import
git-svn-id: http://moon:8086/svn/projects/GeneticAlgorithm@237 fda53097-d464-4ada-af97-ba876c37ca34
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
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")
|
||||
Reference in New Issue
Block a user