diff --git a/GeneticAlgorithm.py b/GeneticAlgorithm.py index efb11bc..7be44a0 100644 --- a/GeneticAlgorithm.py +++ b/GeneticAlgorithm.py @@ -1,4 +1,5 @@ import numpy as np +import copy class FinessEvaluator(object): def __init__(self): @@ -30,19 +31,32 @@ class Cromosome(object): result = self.param[0] + self.param[1]*x + self.param[2]*x**2 return result[0] - def cross(self, p2): + def cross(self, other): a = 0.5 - param1 = (1-a)*self.param + a*p2.param - param2 = (1-a)*p2.param + a*self.param + param1 = (1-a)*self.param + a*other.param + param2 = (1-a)*other.param + a*self.param ca = Cromosome(self.id, param1) - cb = Cromosome(p2.id, param2) + cb = Cromosome(other.id, param2) return ca, cb + def diversity(self, other): + d = self.param - other.param + s = np.mean(d**2) + return s + def mutate(self): gene = int(np.random.rand() * 3) allele = int(5*(0.5 - np.random.rand())) self.param[gene] += allele + def __copy__(self): + print('__copy__()') + return Cromosome(self.name) + + def __deepcopy__(self, arg): + print('__deepcopy__({})'.format(arg)) + return Cromosome(copy.deepcopy(self.name, arg)) + def __str__(self): return "Id: {}, f={:0.6f}, fitAccum={:0.6f}, param=\n{}".format(self.id, self.fitness, self.fitAccum, str(self.param)) @@ -95,13 +109,22 @@ class Population(object): if p < chanceOfReproduction: # 3.) Select parents - p1 = self.select(self.cromosomes) + mom = self.select(self.cromosomes) - p2 = p1 - while(p2 == p1): - p2 = self.select(self.cromosomes) + cand = [] + div = np.empty(0) + # Make diversity selection 1 of 3 candidates + for i in range(0,3): + dad = mom + while(dad == mom): + # Select returns fitter cromosomes with higher probabilty + dad = self.select(self.cromosomes) + cand.append(dad) + div = np.append(div, mom.diversity(dad)) - ca, cb = p1.cross(p2) + # Use best, diverse cromosom + bestCand = np.argmax(div) + ca, cb = mom.cross(cand[bestCand]) newPop[count+0] = ca newPop[count+1] = cb count += 2