Skip to content
Snippets Groups Projects
Commit c9a1f6cb authored by Sepehr Madani's avatar Sepehr Madani
Browse files

Implemented AM-GM crossover

parent 9a2a2976
No related branches found
No related tags found
No related merge requests found
...@@ -18,7 +18,7 @@ class Chromosome: ...@@ -18,7 +18,7 @@ class Chromosome:
return random.randrange(0, 2 ** bit_count) return random.randrange(0, 2 ** bit_count)
class GeneticAlgorithm(BaseAlgorithm): class GeneticBucketAlgorithm(BaseAlgorithm):
""" Finds nulls by running a genetic algorithm on all possible """ Finds nulls by running a genetic algorithm on all possible
discrete values. discrete values.
""" """
...@@ -32,11 +32,13 @@ class GeneticAlgorithm(BaseAlgorithm): ...@@ -32,11 +32,13 @@ class GeneticAlgorithm(BaseAlgorithm):
self.bit_count = options.bit_count self.bit_count = options.bit_count
self.bit_resolution = options.bit_resolution self.bit_resolution = options.bit_resolution
self.mutation_factor = options.mutation_factor self.mutation_factor = options.mutation_factor
self.buckets = [[]] * 8
self.check_parameters() self.check_parameters()
def check_parameters(self): def check_parameters(self):
super().check_parameters() super().check_parameters()
assert len(self.null_degrees) == 1
def solve(self): def solve(self):
self.intialize_sample() self.intialize_sample()
...@@ -44,13 +46,15 @@ class GeneticAlgorithm(BaseAlgorithm): ...@@ -44,13 +46,15 @@ class GeneticAlgorithm(BaseAlgorithm):
self.sort_fitness() self.sort_fitness()
for generation in range(self.gen_to_repeat): for generation in range(self.gen_to_repeat):
for ii in range(self.sample_size // 2, self.sample_size - 1, 2): for ii in range(self.sample_size // 2, self.sample_size - 1, 2):
p1, p2 = random.sample(range(self.sample_size // 2), 2) bucket_idx = random.randrange(4)
p1 = random.choice(self.buckets[bucket_idx])
p2 = random.choice(self.buckets[bucket_idx + 4])
self.crossover(p1, p2, ii, ii + 1) self.crossover(p1, p2, ii, ii + 1)
self.mutate_sample() # self.mutate_sample()
self.update_fitness() self.update_fitness()
self.sort_fitness() self.sort_fitness()
# print(["{:.2f}".format(x.fitness) for x in self.chromosomes[:15]])
return self.make_weights(self.chromosomes[0]) return self.make_weights(self.chromosomes[0])
def mutate_sample(self): def mutate_sample(self):
...@@ -61,36 +65,41 @@ class GeneticAlgorithm(BaseAlgorithm): ...@@ -61,36 +65,41 @@ class GeneticAlgorithm(BaseAlgorithm):
def update_fitness(self, use_exact_angle=True): def update_fitness(self, use_exact_angle=True):
for chromosome in self.chromosomes: for chromosome in self.chromosomes:
values = [ chromosome.fitness = -20 * log10(
-20 * log10(abs(x)) abs(
for x in compute_pattern( compute_pattern(
N=self.N, N=self.N,
k=self.k, k=self.k,
weights=self.make_weights(chromosome), weights=self.make_weights(chromosome),
degrees=self.null_degrees, degrees=self.null_degrees,
use_absolute_value=False,
)[0]
) )
] )
chromosome.fitness = min(values) bucket_idx = int(((cmath.phase(chromosome.fitness) + pi) / (2 * pi)) * 8) % 8
self.buckets[bucket_idx].append(chromosome)
def sort_fitness(self): def sort_fitness(self):
self.chromosomes.sort(key=lambda x: x.fitness, reverse=True) self.chromosomes.sort(key=lambda x: abs(x.fitness), reverse=True)
def make_weights(self, chromosome): def make_weights(self, chromosome):
weights = [] weights = []
for bits in chromosome.gene: for bits in chromosome.gene:
angle = (bits - (2 ** self.bit_count - 1) / 2) * 2 * pi / (2 ** self.bit_resolution) angle = (
(bits - (2 ** self.bit_count - 1) / 2)
* 2
* pi
/ (2 ** self.bit_resolution)
)
weights.append(cmath.exp(1j * angle)) weights.append(cmath.exp(1j * angle))
return weights return weights
def crossover(self, p1, p2, c1, c2): def crossover(self, p1, p2, c1, c2):
self.chromosomes[c1] = deepcopy(self.chromosomes[p1]) for ii in range(self.N):
self.chromosomes[c2] = deepcopy(self.chromosomes[p2]) g1 = p1.gene[ii]
for i in range(self.N): g2 = p2.gene[ii]
if random.random() >= 0.5: self.chromosomes[c1].gene[ii] = (g1 + g2) // 2
self.chromosomes[c1].gene[i], self.chromosomes[c2].gene[i] = ( self.chromosomes[c2].gene[ii] = (g1 + g2 + 1) // 2
self.chromosomes[c1].gene[i],
self.chromosomes[c2].gene[i],
)
def intialize_sample(self): def intialize_sample(self):
self.chromosomes = [ self.chromosomes = [
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment