Commit 02712b2b by Stalin Munoz

adding notebooks and code

parent af66be23
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 2 10:25:43 2016
@author: stan
"""
class DecodingTools:
@staticmethod
def decode_integer(chromosome,position,size):
mask = ((1<<size)-1)<<position
return (chromosome&mask)>>position
@staticmethod
def decode_real_list(chromosome,n,position,size,interval=None,skip=0):
return [\
DecodingTools.decode_real(\
chromosome,position+(size+skip)*i,size,interval)\
if(interval !=None) else \
DecodingTools.decode_normalized_real(\
chromosome,position+(size+skip)*i,size)\
for i in range(0,n)]
@staticmethod
def decode_real(chromosome,position,size,interval):
return (interval[1]-interval[0])* \
DecodingTools.decode_normalized_real(chromosome,position,size) \
+interval[0]
@staticmethod
def decode_normalized_real(chromosome,position,size):
x = DecodingTools.decode_integer(chromosome,position,size)
return x/((1<<(size))-1)
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Created on Thu Nov 3 19:46:35 2016
@author: stan
"""
from environment import Environment
from multiobjective import MultiObjective
from decoding_tools import DecodingTools as dt
import numpy as np
import matplotlib.pyplot as plt
class EC6(Environment,MultiObjective):
def __init__(self,precision=8,n=10,interactive=False):
self.n = n
self.precision = precision
self.interactive = interactive
if(interactive):
plt.ion()
def evaluate(self,population):
for individual in population.individuals:
individual.objectives = \
np.array([self.f1(individual.phenotype),\
self.f2(individual.phenotype)])
def decode(self,population):
for individual in population.individuals:
ch = individual.genotype.chromosome
individual.phenotype = \
np.array(dt.decode_real_list(ch,self.n,0,self.precision))
def get_chromosome_length(self):
return self.precision*self.n
def get_number_of_objectives(self):
return 2
def get_optimization_type(self):
return np.array([-1, -1])
def f1(self,x):
return 1-np.exp(-4*x[0])*(np.sin(6*np.pi*x[0])**6)
def g(self,x):
return 1 + 9*(np.sum(x[1:])/(self.n-1))**0.25
def f2(self,x):
g = self.g(x)
f = self.f1(x)
return g*(1 -(f/g)**2)
def show(self,population=None,colors='blue',clear = True):
if(clear):
plt.clf()
objectives =[x.objectives for x in population.individuals]
X = [x.item(0) for x in objectives]
Y = [x.item(1) for x in objectives]
plt.scatter(X,Y,color=colors)
X = np.linspace(0,1,100)
Y= 1 - X**2
plt.plot(X,Y,'red')
plt.grid()
if(self.interactive):
plt.pause(0.05)
else:
plt.show()
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Created on Fri Aug 26 09:46:33 2016
@author: stan
"""
from environment import Environment
class Ones(Environment):
def __init__(self,n):
self.n = n
def evaluate(self,population):
for individual in population.individuals:
bits = individual.genotype.chromosome
individual.fitness = self.contar_unos(bits)
def get_gene_template(self):
return [([self.n,0])]
def decode(self,population):
for individual in population.individuals:
individual.phenotype = individual.genotype.chromosome
def get_chromosome_length(self):
return self.n
def contar_unos(self, bits):
return bin(bits).count("1")
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Created on Fri Aug 26 09:46:33 2016
@author: stan
"""
from decoding_tools import DecodingTools as dt
from environment import Environment
#import numpy as np
class SimpleFunction(Environment):
function = lambda x:x*x-3*x+6
#function = lambda x:(x*x-3*x+6)*np.sin(x)/(np.sqrt(1+np.sin(3*x)))
def evaluate(self,population):
for individual in population.individuals:
x = individual.phenotype
individual.fitness = -SimpleFunction.function(x)
def decode(self,population):
for individual in population.individuals:
individual.phenotype = \
dt.decode_real(individual.genotype.chromosome,0,6,(0.5,0.7))
def get_chromosome_length(self):
return 6
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Created on Fri Aug 26 09:46:33 2016
@author: stan
"""
from abc import ABCMeta, abstractmethod
class Environment:
__metaclass__ = ABCMeta
@abstractmethod
def evaluate(self,population):
pass
@abstractmethod
def get_gene_template(self):
pass
@abstractmethod
def compute_distance(self,individual1,individual2):
pass
@abstractmethod
def compute_normalized_distance(self,individual1,individual2):
pass
@abstractmethod
def decode(self,population):
pass
@abstractmethod
def get_chromosome_length(self):
pass
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 23 08:31:05 2016
@author: stan
"""
import numpy as np
class FitnessSharing:
@staticmethod
def scale_fitness(population):
sharing_domain = population.parameters['sharing.domain']
theta_share = population.parameters['theta.share']
environment = population.environment
theta_share = (theta_share/100)* \
(environment.get_chromosome_length() if \
sharing_domain=='genotype' else 1)
alpha = population.parameters['alpha.share']
distance = FitnessSharing.count if sharing_domain=='genotype' \
else population.environment.compute_distance
individuals = population.individuals
distances = np.zeros((population.size,population.size))
for i in range(0,population.size):
for j in range(i,population.size):
distances[i,j] = \
distance(individuals[i],individuals[j])
distances[j,i] = distances[i,j]
sharing = np.vectorize(FitnessSharing.sharing_function)
scaled_fitness = \
[population.individuals[i].fitness/ \
sum(sharing(distances[i],theta_share,alpha)) \
for i in range(0, population.size)]
for i in range(0,population.size):
population.individuals[i].fitness = scaled_fitness[i]
@staticmethod
def count(individual1,individual2):
diff = individual1.genotype.chromosome^individual2.genotype.chromosome
c = 0
while(diff !=0 ):
diff = diff&(diff-1)
c = c + 1
return c
@staticmethod
def sharing_function(distance,theta_share,alpha):
return 1 - (distance/theta_share)**alpha if \
distance < theta_share else 0
@staticmethod
def beta_scaling(population):
beta = population.parameters['beta.fitness.scaling']
for i in range(0,population.size):
fitness = population.individuals[i].fitness
population.individuals[i].fitness = fitness**beta
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Created on Fri Aug 19 09:17:49 2016
@author: stan
"""
from genetic_ops import GeneticOperators
from population import Population
from fitness_sharing import FitnessSharing
from niche_clearing import NicheClearing
from selection import Selection
import warnings
class GeneticAlgorithm:
def __init__(self,environment,parameters):
self.parameters = parameters
self.environment = environment
self.population = Population(environment,parameters)
self.environment.decode(self.population)
self.environment.evaluate(self.population)
self.scale_fitness(self.population)
def evolve(self):
for i in range(0,self.parameters['n.generations']):
mating_pool = GeneticOperators.select(self.population)
new_pop = GeneticOperators.crossover(mating_pool)
GeneticOperators.mutate_in_place(new_pop)
self.environment.decode(new_pop)
self.environment.evaluate(new_pop)
self.scale_fitness(new_pop)
if('elitism' in self.parameters and \
self.parameters['elitism']):
if(self.population.parameters['type']== \
'nsga-ii'):
union = Population(self.population.environment,\
self.population.parameters,\
self.population.individuals+new_pop.individuals)
new_pop = Selection.pareto_crowded(union)
else:
new_pop =\
Population(self.population.environment,\
self.population.parameters,\
sorted(self.population.individuals+new_pop.individuals,\
key=lambda x:x.fitness,reverse=True)\
[:self.population.size])
self.population = new_pop
self.report(i,self.parameters['n.generations'])
self.report()
def scale_fitness(self,population):
if('fitness.scaling' in self.parameters and \
self.parameters['fitness.scaling']):
FitnessSharing.beta_scaling(population)
if('fitness.sharing' in self.parameters and \
self.parameters['fitness.sharing']):
FitnessSharing.scale_fitness(population)
if('niche.clearing' in self.parameters and \
self.parameters['niche.clearing']):
NicheClearing.scale_fitness(population)
def report(self,generation=0,total=0):
step = max(1,int(total/10))
progress = int(generation/step) if step != 0 else 100
if(generation==total):
print('\r'*80+'Done'+' '*76)
self.plot()
elif(generation%step==0):
print('\r'*80+"Progress: {num:02d}%".format(\
num=progress*10)+\
" ["+chr(187)*int(progress*5)+chr(183)*(10*5-int(progress*5))+\
"]",end="")
self.plot()
def plot(self):
with warnings.catch_warnings():
warnings.simplefilter("ignore")
if(hasattr(self.environment,'show')):
self.environment.show(self.population,clear=True)
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Created on Fri Aug 19 10:49:31 2016
@author: stan
"""
from random import randint
from genotype import Genotype
from numpy import random
from population import Population
from individual import Individual
from selection import Selection
from permutation_cross import PermutationCrossover
import numpy as np
class GeneticOperators:
selections={"tournament.selection":Selection.tournament,
"roulettewheel.selection":Selection.roulettewheel,
"ranking.selection":Selection.ranking,
"pareto.tournament":Selection.pareto_tournament}
permutations={"permutation.ox":PermutationCrossover.ox_crossover,
"permutation.ox1":PermutationCrossover.ox1_crossover,
"permutation.ox2":PermutationCrossover.ox2_crossover,
"permutation.pmx":PermutationCrossover.pmx_crossover,
"permutation.pmx.grefenstette":
PermutationCrossover.pmx_grefenstette_crossover,
"permutation.pos":PermutationCrossover.pos_crossover,
"permutation.cx":PermutationCrossover.cx_crossover}
keys = list(permutations.keys())
@staticmethod
def crossover(population):
#assumes individuals are shuffled
new_pop = []
for i in range(0,population.size>>1):
individual1 = population.individuals[i]
individual2 = population.individuals[population.size-i-1]
if(random.uniform() < population.parameters['p.crossover']):
type = population.parameters['crossover.type'] \
if (population.parameters['crossover.type'] \
!= 'permutation.all.operators') else \
np.random.choice(GeneticOperators.keys)
children = GeneticOperators.permutation_crossover_individuals(\
individual1,individual2,type) \
if(population.parameters['type']=='permutation') else \
GeneticOperators.crossover_individuals(\
individual1,individual2)
else:
children = [\
Individual(individual1.genotype,\
np.array(individual1.phenotype)),\
Individual(individual2.genotype,\
np.array(individual2.phenotype))]
new_pop = new_pop + children
return \
Population(population.environment, population.parameters,new_pop)
@staticmethod
def crossover_individuals(individual1,individual2,type = 'single'):
genotype1 = individual1.genotype
genotype2 = individual2.genotype
crossp = randint(1,genotype1.n-1)
mask1 = ((1<<(genotype1.n-crossp))-1)<< crossp
mask2 = (1<<crossp)-1
ch1 = mask1&genotype1.chromosome|mask2&genotype2.chromosome
ch2 = mask1&genotype2.chromosome|mask2&genotype1.chromosome
child1 = Genotype(genotype1.n,ch1)
child2 = Genotype(genotype1.n,ch2)
return [Individual(child1),Individual(child2)]
@staticmethod
def permutation_crossover_individuals(individual1,individual2,type):
return GeneticOperators.permutations[type](individual1,individual2)
@staticmethod
def mutate_in_place(population):
if(population.parameters['type']=='permutation'):
length = len(population.individuals[0].phenotype)
mutations = random.binomial(length*population.size,\
population.parameters['p.mutation'])
to_mutate = [(randint(0,population.size-1),randint(0,length-1),\
randint(0,length-1)) for i in range(0,mutations)]
for ind,a,b in to_mutate:
temp = population.individuals[ind].phenotype[a]
population.individuals[ind].phenotype[a] = \
population.individuals[ind].phenotype[b]
population.individuals[ind].phenotype[b] = temp
else:
length = population.environment.get_chromosome_length();
mutations = random.binomial(length*population.size,\
population.parameters['p.mutation'])
to_mutate = [(randint(0,population.size-1),randint(0,length-1)) \
for i in range(0,mutations)]
for ind,pos in to_mutate:
population.individuals[ind].genotype.chromosome = \
population.individuals[ind].genotype.chromosome^(1<<pos)
@staticmethod
def select(population):
selection_method = \
GeneticOperators.selections[population.parameters['selection.type']]
return selection_method(population)
# -*- coding: utf-8 -*-
"""
Created on Fri Aug 19 09:17:49 2016
@author: stan
"""
from struct import unpack
from os import urandom
from functools import reduce
from math import ceil
class Genotype:
def __init__(self,n,chromosome=None):
self.n = n
if(chromosome != None):
self.chromosome = chromosome
else:
if(self.n==64):
chromosome = unpack("!Q",urandom(8))[0]
elif(self.n<64):
chromosome = unpack("!Q",urandom(8))[0] & \
((1<<self.n)-1)
else:
m = ceil(self.n/64)
rand = [0]+[unpack("!Q",urandom(8))[0] for i in range(0,m)]
chromosome = reduce(lambda x,y:(x<<64)|y,rand) &\
((1<<self.n)-1)
self.chromosome = chromosome
def __str__(self):
return ("{0:0"+str(self.n)+"b}").format(self.chromosome)
# -*- coding: utf-8 -*-
"""
Created on Fri Aug 26 09:22:10 2016
@author: stan
"""
class Individual:
def __init__(self,genotype=None,phenotype=None):
self.genotype = genotype
self.phenotype = phenotype
def __str__(self):
return \
(('genotype: '+ str(self.genotype)) \
if self.genotype is not None else '') + \
(('phenotype: '+ str(self.phenotype)) \
if self.phenotype is not None else '') + \
(('fitness: ' + str(self.fitness)) \
if hasattr(self,'fitness') else '') + \
(('objectives: '+str(self.objectives))
if hasattr(self,'objectives') else '')
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Created on Fri Oct 21 08:15:41 2016
@author: stan
"""
from environment import Environment
from multiobjective import MultiObjective
from decoding_tools import DecodingTools as dt
import numpy as np
import matplotlib.pyplot as plt
class MOP4(Environment,MultiObjective):
def __init__(self,precision=15,n=3,interactive=False):
self.n = n
self.precision = precision
self.interactive = interactive
if(interactive):
plt.ion()
def evaluate(self,population):
for individual in population.individuals:
individual.objectives = \
np.array([MOP4.f1(individual.phenotype),\
MOP4.f2(individual.phenotype)])
def decode(self,population):
for individual in population.individuals:
ch = individual.genotype.chromosome
individual.phenotype = \
np.array([\
dt.decode_real(ch,0,self.precision,(-5,5)),\
dt.decode_real(ch,self.precision,self.precision,(-5,5)),
dt.decode_real(ch,2*self.precision,self.precision,(-5,5))])
def get_chromosome_length(self):
return self.precision*self.n
def get_number_of_objectives(self):
return 2
def get_optimization_type(self):
return np.array([-1,-1])
@staticmethod
def f1(x):
n = len(x)
return sum(-10*np.exp(-0.2*np.sqrt(x[:n-1]**2+x[1:n]**2)))
def f2(x):
#return sum(np.abs(x)**0.8 + 5*np.sin(x)**3)
return sum(np.abs(x)**0.8 + 5*np.sin(x**3))
def show(self,population,colors='blue',clear = True):
if(clear):
plt.clf()
objectives =[x.objectives for x in population.individuals]
X = [x.item(0) for x in objectives]
Y = [x.item(1) for x in objectives]
plt.scatter(X,Y,color=colors)
plt.grid()
if(self.interactive):
plt.pause(0.05)
else:
plt.show()
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 30 10:29:57 2016
@author: stan
"""
from abc import ABCMeta, abstractmethod
class MultiObjective:
__metaclass__ = ABCMeta
@abstractmethod
def get_number_of_objectives(self):
pass
@abstractmethod
def get_optimization_type(self):
pass
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 30 09:24:59 2016
@author: stan
"""
class NicheClearing:
@staticmethod
def scale_fitness(population):
env = population.environment
sigma = population.parameters['sigma.niche.clearing']/100
kappa = population.parameters['kappa.niche.clearing']
individuals = sorted(population.individuals,\
key=lambda x:x.fitness,reverse=True)
for i in range(0,population.size):
if(individuals[i].fitness>0):
n_winners = 1
for j in range(i+1,population.size):
if(individuals[j].fitness>0 and \
env.compute_normalized_distance(individuals[i],\
individuals[j])<sigma):
if n_winners < kappa:
n_winners = n_winners + 1
else:
individuals[j].fitness = 0
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 30 10:34:34 2016
@author: stan
"""
import math
import numpy as np
class Pareto:
@staticmethod
def fast_non_dominated_sort(population):
fronts = [[]]
S = [[] for i in range(0, population.size)]
n = [0]*population.size
individuals = population.individuals
for i in range(0, population.size):
for j in range(i+1,population.size):
dominance = \
Pareto.dominates(individuals[i],individuals[j],\
population.environment)
if(dominance[0]):
S[i].append(j)
n[j] = n[j] + 1
elif(dominance[1]):
S[j].append(i)
n[i] = n[i] + 1
if(n[i]==0):
fronts[0].append(i)
i = 0
while(fronts[i]):
H = []
for p in fronts[i]:
for q in S[p]:
n[q] = n[q]-1
if(n[q]==0):
H.append(q)
i = i + 1
fronts.append(H)
fronts.pop()
return fronts
@staticmethod
def get_front_membership(fronts):
membership={}
for i in range(0,len(fronts)):
for j in fronts[i]:
membership[j] = i
return membership
@staticmethod
def crowding_distance(population):
l = population.size
distances = [0]*population.size
n = population.environment.get_number_of_objectives()
for i in range(0,n):
I = sorted(enumerate(population.individuals),\
key = lambda x:x[1].objectives[i])
distances[I[0][0]] = math.inf
distances[I[l-1][0]] = math.inf
for j in range(1,l-1):
distances[I[j][0]] = distances[I[j][0]] + \
(population.individuals[I[j+1][0]].objectives[i] - \
population.individuals[I[j-1][0]].objectives[i])
return distances
@staticmethod
def dominates(individual1,individual2,environment):
# array in {-1,+1}; -1 minimization, +1 maximization
direction = environment.get_optimization_type()
x1 = np.multiply(individual1.objectives,direction)
x2 = np.multiply(individual2.objectives,direction)
diff = x1 - x2
negative = np.where(diff<0)[0]
positive = np.where(diff>0)[0]
dom_1_2 = (False if(len(negative)>0) else len(positive)>0)
dom_2_1 = (False if(len(positive)>0) else len(negative)>0)
return [dom_1_2,dom_2_1]
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Created on Fri Nov 18 00:30:32 2016
@author: stan
"""
from numpy import random
from individual import Individual
import numpy as np
class PermutationCrossover:
#Partially-mapped crossover
@staticmethod
def pmx_crossover(individual1,individual2):
n,i,f,i_central,i_sides= PermutationCrossover.mapping_sections(\
individual1,individual2)
child1,child2 = PermutationCrossover.child_templates(n)
map_1_2,map_2_1 = PermutationCrossover.find_mappings(\
i_central,individual1,individual2)
child1[i_central]= individual2.phenotype[i_central]
child2[i_central]= individual1.phenotype[i_central]
sides = list(filter(lambda x: x not in i_central,\
range(0,n)))
child1[sides] = [i if i not in map_2_1.keys() else\
PermutationCrossover.alternative(i,map_2_1) \
for i in individual1.phenotype[sides]]
child2[sides] = [i if i not in map_1_2.keys() else\
PermutationCrossover.alternative(i,map_1_2) \
for i in individual2.phenotype[sides]]
return [Individual(phenotype=child1),Individual(phenotype=child2)]
@staticmethod
def cx_crossover(individual1,individual2):
n = len(individual1.phenotype)
child1= individual2.phenotype.copy()
child2= individual1.phenotype.copy()
city_pos = 0
map_1 = {individual1.phenotype[i]:i for i in range(0,n)}
while(True):
city_pos = PermutationCrossover.apply_mapping(\
child1,child2,individual1,individual2,city_pos,map_1)
if(map_1[individual2.phenotype[city_pos]] is 0):
PermutationCrossover.apply_mapping(\
child1,child2,individual1,individual2,city_pos,map_1)
break
return [Individual(phenotype=child1),Individual(phenotype=child2)]
@staticmethod
def apply_mapping(child1,child2,individual1,individual2,city_pos,map_1):
child1[city_pos] = individual1.phenotype[city_pos]
child2[city_pos] = individual2.phenotype[city_pos]
return map_1[individual2.phenotype[city_pos]]
#Order crossover
@staticmethod
def ox_crossover(individual1,individual2):
n,i,f,i_central,i_sides= PermutationCrossover.mapping_sections(\
individual1,individual2)
p1_central = set(individual1.phenotype[i_central])
p2_central = set(individual2.phenotype[i_central])
centrals = p1_central.union(p2_central)
rest_1 = list(filter(lambda x:x[1] not in centrals, \
enumerate(individual1.phenotype)))
rest_2 = list(filter(lambda x:x[1] not in centrals, \
enumerate(individual2.phenotype)))
rest_1 = np.array([x[1] for x in \
list(filter(lambda x:x[0]>=f,rest_1))+\
(list(filter(lambda x:x[0]<i,rest_1)))])
rest_2 = np.array([x[1] for x in \
list(filter(lambda x:x[0]>=f,rest_2))+\
(list(filter(lambda x:x[0]<i,rest_2)))])
head_1 = np.array(list(filter(lambda x:x not in p2_central,\
individual1.phenotype[i_central])))
head_2 = np.array(list(filter(lambda x:x not in p1_central,\
individual2.phenotype[i_central])))
child1 = PermutationCrossover.build_child(\
head_1,individual2.phenotype[i_central],rest_1)
child2= PermutationCrossover.build_child(\
head_2,individual1.phenotype[i_central],rest_2)
return [Individual(phenotype=child1),Individual(phenotype=child2)]
@staticmethod
def build_child(head,middle,rest):
if head.size>0 and rest.size>0:
return np.concatenate((head,middle,rest))
elif head.size>0 and rest.size==0:
return np.concatenate((head,middle))
elif head.size==0 and rest.size>0:
return np.concatenate((middle,rest))
else:
return middle
@staticmethod
def ox1_crossover(individual1,individual2):
n,i,f,i_central,i_sides= PermutationCrossover.mapping_sections(\
individual1,individual2)
child1,child2 = PermutationCrossover.child_templates(n)
p1_central = set(individual1.phenotype[i_central])
p2_central = set(individual2.phenotype[i_central])
child1[i_central]= individual1.phenotype[i_central]
child2[i_central]= individual2.phenotype[i_central]
child1[i_sides[:n-(f-i)-1]] = list(filter(lambda x:x not in p1_central,\
individual2.phenotype[i_sides]))
child2[i_sides[:n-(f-i)-1]] = list(filter(lambda x:x not in p2_central,\
individual1.phenotype[i_sides]))
return [Individual(phenotype=child1),Individual(phenotype=child2)]
@staticmethod
def ox2_crossover(individual1,individual2):
n,poss = PermutationCrossover.random_crossover_points(\
individual1,individual2)
child1 = np.copy(individual1.phenotype)
child2 = np.copy(individual2.phenotype)
p_1 = individual1.phenotype[poss]
p_2 = individual2.phenotype[poss]
pos_1 = [i[0] for i in enumerate(individual1.phenotype) \
if i[1] in set(p_2)]
pos_2 = [i[0] for i in enumerate(individual2.phenotype) \
if i[1] in set(p_1)]
child1[pos_1]= p_2
child2[pos_2]= p_1
return [Individual(phenotype=child1),Individual(phenotype=child2)]
@staticmethod
def random_crossover_points(individual1,individual2):
n = len(individual1.phenotype)
#sorted unique indices
poss = np.unique(np.random.choice(list(range(0,n)),\
np.random.randint(1,n)))
return (n,poss)
@staticmethod
def pos_crossover(individual1,individual2):
n,poss = PermutationCrossover.random_crossover_points(\
individual1,individual2)
child1,child2 = PermutationCrossover.child_templates(n)
child1[poss]=individual2.phenotype[poss]
child2[poss]=individual1.phenotype[poss]
poss_set = set(poss)
p1_sel = set(individual1.phenotype[poss])
p2_sel = set(individual2.phenotype[poss])
pos_res = list(filter(lambda x:x not in poss_set,range(0,n)))
rest_1 = list(filter(lambda x:x not in p2_sel,individual1.phenotype))
rest_2 = list(filter(lambda x:x not in p1_sel,individual2.phenotype))
child1[pos_res] = rest_1
child2[pos_res] = rest_2
return [Individual(phenotype=child1),Individual(phenotype=child2)]
@staticmethod
def pmx_grefenstette_crossover(individual1,individual2):
n,i,f,i_central,i_sides= PermutationCrossover.mapping_sections(\
individual1,individual2)
child1_central = individual2.phenotype[i_central]
child2_central = individual1.phenotype[i_central]
p1_central = set(child1_central)
p2_central = set(child2_central)
child1_rest = np.array(list(filter(lambda x:x not in p1_central,\
individual1.phenotype)))
child2_rest = np.array(list(filter(lambda x:x not in p2_central,\
individual1.phenotype)))
pos_1 = np.where(individual1.phenotype==child1_central[0])[0][0]
pos_2 = np.where(individual2.phenotype==child2_central[0])[0][0]
child1 = PermutationCrossover.build_child(child1_rest[:pos_1],\
child1_central,child1_rest[pos_1:])
child2 = PermutationCrossover.build_child(child2_rest[:pos_2],\
child2_central,child2_rest[pos_2:])
return [Individual(phenotype=child1),Individual(phenotype=child2)]
@staticmethod
def mapping_sections(individual1,individual2):
n = len(individual1.phenotype)
i,f = np.sort(random.randint(0,n,2))
i_central = list(range(i,f+1))
i_sides = [i%n for i in range(f+1,n+f+1)]
return (n,i,f,i_central,i_sides)
@staticmethod
def find_mappings(i_central,individual1,individual2):
map_1_2 = {individual1.phenotype[i]:individual2.phenotype[i] \
for i in i_central}
map_2_1 = {individual2.phenotype[i]:individual1.phenotype[i] \
for i in i_central}
return (map_1_2,map_2_1)
@staticmethod
def alternative(city,map):
while(city in map.keys()):
city = map[city]
return city
@staticmethod
def child_templates(n):
return ( np.array([0]*n), np.array([0]*n))
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Created on Fri Aug 26 09:21:41 2016
@author: stan
"""
from genotype import Genotype
from individual import Individual
from numpy import random
import numpy as np
class Population:
def __init__(self,environment,parameters,individuals=None):
self.environment = environment
self.parameters = parameters
self.size = self.parameters['n.individuals']
if individuals==None:
self.individuals = [self.create_individual() \
for i in range(0,self.parameters['n.individuals'])]
else:
self.individuals = individuals
self.size = len(individuals)
def create_individual(self):
if(self.parameters['type']=='permutation'):
phen = \
np.array(list(range(0,self.environment.get_chromosome_length())))
random.shuffle(phen)
individual = \
Individual(phenotype=phen)
else:
individual = \
Individual(Genotype(self.environment.get_chromosome_length()))
return individual
def __str__(self):
return "\n".join([str(i) for i in self.individuals])
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 9 10:09:34 2016
@author: stan
"""
from functools import reduce
from numpy import random,sort,cumsum
from random import choice,shuffle
from math import ceil,sqrt
from population import Population
from pareto import Pareto
class Selection:
@staticmethod
def tournament(population):
k = population.parameters['tournament.size']
return Population(population.environment, population.parameters,\
[max([choice(population.individuals) \
for i in range(0,k)],key=lambda x:x.fitness)\
for i in range(0,population.size)])
@staticmethod
def pareto_tournament(population):
k = population.parameters['tournament.size']
fronts = Pareto.fast_non_dominated_sort(population)
distances = Pareto.crowding_distance(population)
indices = range(0,population.size)
membership = Pareto.get_front_membership(fronts)
individuals = population.individuals
return Population(population.environment, population.parameters,\
[individuals[\
reduce(lambda x,y:\
Selection.best_crowded_comparison(x,y,membership,distances),\
[choice(indices) for i in range(0,k)])]\
for i in range(0,population.size)])
@staticmethod
def best_crowded_comparison(individual1,individual2,membership,distances):
if(membership[individual1]<membership[individual2]):
return individual1
elif(membership[individual2]<membership[individual1]):
return individual2
elif(distances[individual1]>distances[individual2]):
return individual1
else:
return individual2
@staticmethod
def roulettewheel(population):
pointers = sort(random.uniform(size=population.size))
total_fitness = reduce(lambda x,y:x+y, \
map(lambda i:i.fitness,population.individuals))
probabilities = map(lambda x:x.fitness/total_fitness, \
population.individuals)
selected = []
delimiters = cumsum(list(probabilities))
i_p = 0
i_d = 0
while i_p < population.size and i_d < population.size:
while i_p < population.size and pointers[i_p] < delimiters[i_d]:
selected=selected+[population.individuals[i_d]]
i_p = i_p + 1
i_d = i_d + 1
shuffle(selected)
return Population(population.environment, population.parameters,\
selected)
@staticmethod
def ranking(population):
n = population.size
pointers = random.uniform(1,(n*(n+1))>>1,n)
population.individuals.sort(key=lambda x: x.fitness)
selected = [population.individuals[\
int(ceil((-1 + sqrt(1+8*p))/2))-1] for p in pointers]
return Population(population.environment, population.parameters,\
selected)
@staticmethod
def pareto_crowded(population):
fronts = Pareto.fast_non_dominated_sort(population)
distances = Pareto.crowding_distance(population)
front = 0
selected = []
while(len(selected)+len(fronts[front])<(population.size>>1)):
selected = selected + \
[population.individuals[i] for i in fronts[front]]
front = front + 1
n = (population.size>>1) - len(selected)
distances_last_front = [(distances[i],population.individuals[i]) \
for i in fronts[front]]
sorted_distances = sorted(distances_last_front,key=lambda x:x[0],\
reverse=True)
selected = selected + [i[1] for i in sorted_distances[:n]]
return \
Population(population.environment,population.parameters,selected)
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Created on Sat Sep 17 11:29:30 2016
@author: stan
"""
from environment import Environment
import numpy as np
from decoding_tools import DecodingTools as dt
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
class Shekel(Environment):
A = np.matrix([
[0.5,0.5],
[0.25,0.25],
[0.25,0.75],
[0.75,0.25],
[0.75,0.75]])
c = np.matrix([
[0.002],
[0.005],
[0.005],
[0.005],
[0.005],
])
def __init__(self,precision=10):
self.precision = precision
self.fig = plt.figure()
self.ax = Axes3D(self.fig)
def evaluate(self,population):
for individual in population.individuals:
individual.fitness = Shekel.function(individual.phenotype)
def decode(self,population):
for individual in population.individuals:
ch = individual.genotype.chromosome
individual.phenotype = \
np.matrix([\
dt.decode_normalized_real(ch,0,self.precision),\
dt.decode_normalized_real(ch,self.precision,self.precision)])
@staticmethod
def function(x):
d = (np.kron(x,np.ones((5,1)))-Shekel.A)
return np.sum(1/(np.sum(np.multiply(d,d),axis=1) + Shekel.c))
def get_chromosome_length(self):
return self.precision*2
def compute_distance(self,individual1,individual2):
return np.linalg.norm(individual1.phenotype-individual2.phenotype)
def compute_normalized_distance(self,individual1,individual2):
return np.linalg.norm(individual1.phenotype-individual2.phenotype)
def show(self,population=None,clear=False):
f = np.vectorize(lambda x,y: Shekel.function(np.array([x,y])))
if(population != None):
fen =[x.phenotype for x in population.individuals]
X = [x.item(0) for x in fen]
Y = [x.item(1) for x in fen]
else:
x = np.linspace(0,1,100)
y = np.linspace(0,1,100)
X,Y = np.meshgrid(x,y)
Z = f(X,Y)
if(population != None):
self.ax.scatter(X,Y,Z,cmap=cm.jet)
else:
self.ax.plot_surface(X,Y,Z,rstride=5,cstride=5,cmap=cm.jet)
plt.show()
\ No newline at end of file
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Sep 23 07:36:15 2018
@author: stan
"""
import random
x = random.randint(0,1<<1000000)
def count_ones(number):
c = 0
while(number !=0 ):
number = number&(number-1)
c = c + 1
return c
%timeit bin(x).count("1")
%timeit count_ones(x)
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment