Hello @mccurcio ,
No, my function does not have any problem. I just want to implement my code with more speed. you may suggest an alternative method, or recommend aforementioned code some minor modification so as to spped up my code.
now I place the original function which uses the above code:
from random import uniform
import numpy as np
from numpy.random import randint
from numpy import ones
from numpy import cos
from numpy import sin
from numpy import exp
from numpy import pi
from numpy import abs
from numpy import sum
SOLUTION_SEQUENCE = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
TOURNAMENT_SIZE = 20
MAX_FITNESS = 10
FREQUENCY = 28e9
LIGHT_SPEED = 3e8
WAVELENGTH = LIGHT_SPEED / FREQUENCY
K = 2 * pi / WAVELENGTH
PHI = 0
RING_ELEMENT_NUM = np.array([6, 12, 18, 25, 31, 37, 43, 50, 56])
RING_NUM = 9
CHROMOSOME_LENGTH = int(sum(RING_ELEMENT_NUM))
THETA_range_mul10 = np.array(list(range(-900, 901)))
class Individual:
def __init__(self):
self.cur = None
self.genes = [randint(0, 1) for _ in range(CHROMOSOME_LENGTH)]
def get_fitness(self):
fitness = self.fitness_function(self.genes, self.fn_uniform(), self.fn_com(self.genes))
return fitness
def fitness_function(self, Ipop, fn_uni, fn_com):
WF1 = 0.8
WF2 = 0.2
CF = WF1 * abs(fn_com[1] + fn_com[2]) / abs(self.AF(Ipop, 0))
+ WF2 * abs(fn_com[0] - fn_uni)
return CF
def fn_uniform(self):
AF_uni = self.AF_uniform()
null1 = 0
null2 = 0
i = 0
while i <= 898:
if AF_uni[int(i + 901) + 1] > AF_uni[int(i + 901)]:
null1 = i / 10
break
i += 1
i = 0
while i <= 898:
if AF_uni[int(-i + 901) - 1] > AF_uni[int(i + 901)]:
null2 = i / 10
break
i += 1
fn = abs(null2 - null1)
return [fn]
def fn_com(self, I_pop):
msl1 = 0
msl2 = 0
AF_com = list(range(-900, 901))
theta = -900
while theta <= 900:
AF_com[theta + 900] = self.AF(I_pop, theta / 10)
theta += 1
null1 = 0
null2 = 0
i = 0
while i <= 898:
if AF_com[int(i + 901) + 1] > AF_com[int(i + 901)]:
index_msl1 = AF_com.index(max(AF_com[i:]))
msl1 = max(AF_com[i:])
null1 = i / 10
break
i += 1
i = 0
while i <= 898:
if AF_com[int(-i + 901) - 1] > AF_com[int(i + 901)]:
index_msl2 = AF_com.index(max(AF_com[0:i]))
msl2 = max(AF_com[i:])
null2 = i / 10
break
i += 1
fn = abs(null2 - null1)
return [fn, msl1, msl2]
def AF_uniform(self):
AF_uni = list(range(-900, 901))
cur = ones(CHROMOSOME_LENGTH)
theta = -900
while theta < 900:
theta += 1
AF_uni[int(theta + 900)] = self.AF(cur, theta / 10)
return AF_uni
def AF(self, cur, theta):
AF_out = 1
self.cur = np.array(cur)
AF_out = 1 + sum(sum(self.cur[i] * exp(1j * K * (m * WAVELENGTH / 2) *
sin(theta) * cos(PHI - 2 * pi * (i - 1) / RING_ELEMENT_NUM[m]))
for i in range(RING_ELEMENT_NUM[m], int(sum(RING_ELEMENT_NUM[0:m])))) for m in
np.array(list(range(int(RING_NUM)))))
return AF_out
def set_gene(self, index, value):
self.genes[index] = value
def __repr__(self):
return ''.join(str(e) for e in self.genes)
class Population:
def __init__(self, population_size):
self.population_size = population_size
self.individuals = [Individual() for _ in range(population_size)]
self.new = 0
def get_fittest(self):
fittest = self.individuals[0]
for individual in self.individuals[1:]:
self.new += 1
print(self.new)
if individual.get_fitness() > fittest.get_fitness():
fittest = individual
return fittest
def get_fittest_elitism(self, n):
self.individuals.sort(key=lambda ind: ind.get_fitness(), reverse=True)
print(self.individuals)
print(self.individuals[:n])
return self.individuals[:n]
def get_size(self):
return self.population_size
def get_individual(self, index):
return self.individuals[index]
def save_individual(self, index, individual):
self.individuals[index] = individual
class GeneticAlgorithm:
def __init__(self, population_size=100, crossover_rate=0.65, mutation_rate=0.1, elitism_param=5):
self.population_size = population_size
self.crossover_rate = crossover_rate
self.mutation_rate = mutation_rate
self.elitism_param = elitism_param
self.fittest = 0
self.fittest_value = 0
def run(self):
pop = Population(self.population_size)
generation_counter = 0
while generation_counter < 1000:
generation_counter += 1
self.fittest = pop.get_fittest()
self.fittest_value = self.fittest.get_fitness()
print('Generation #%s - fittest is: %s with fitness value %s' % (
generation_counter, self.fittest, self.fittest_value))
pop = algorithm.evolve_population(pop)
print('Solution found...')
print(pop.get_fittest())
def evolve_population(self, population):
next_population = Population(self.population_size)
# elitism: the top fittest individuals from previous population survive
# so we copy the top 5 individuals to the next iteration (next population)
# in this case the population fitness can not decrease during the iterations
next_population.individuals.extend(population.get_fittest_elitism(self.elitism_param))
# crossover
for index in range(self.elitism_param, next_population.get_size()):
first = self.random_selection(population)
second = self.random_selection(population)
next_population.save_individual(index, self.crossover(first, second))
# mutation
for individual in next_population.individuals:
self.mutate(individual)
print(next_population)
return next_population
def crossover(self, offspring1, offspring2):
cross_individual = Individual()
start = randint(CHROMOSOME_LENGTH)
end = randint(CHROMOSOME_LENGTH)
if start > end:
start, end = end, start
cross_individual.genes = offspring1.genes[:start] + offspring2.genes[start:end] + offspring1.genes[end:]
return cross_individual
def mutate(self, individual):
for index in range(CHROMOSOME_LENGTH):
if uniform(0, 1) <= self.mutation_rate:
individual.genes[index] = randint(CHROMOSOME_LENGTH)
# this is called tournament selection
def random_selection(self, actual_population):
new_population = Population(TOURNAMENT_SIZE)
for i in range(new_population.get_size()):
random_index = randint(new_population.get_size())
new_population.save_individual(i, actual_population.get_individual(random_index))
return new_population.get_fittest()
if __name__ == '__main__':
algorithm = GeneticAlgorithm(100, 0.8, 0.015)
algorithm.run()