Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 464bfd6

Browse files
Batch fitness for adaptive mutation
1 parent 63e8312 commit 464bfd6

File tree

2 files changed

+39
-14
lines changed

2 files changed

+39
-14
lines changed

‎pygad/pygad.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,8 +1531,7 @@ def cal_pop_fitness(self):
15311531
elif (self.keep_elitism > 0) and (self.last_generation_elitism is not None) and (len(self.last_generation_elitism) > 0) and (list(sol) in last_generation_elitism_as_list):
15321532
# Return the index of the elitism from the elitism array 'self.last_generation_elitism'.
15331533
# This is not its index within the population. It is just its index in the 'self.last_generation_elitism' array.
1534-
elitism_idx = last_generation_elitism_as_list.index(
1535-
list(sol))
1534+
elitism_idx = last_generation_elitism_as_list.index(list(sol))
15361535
# Use the returned elitism index to return its index in the last population.
15371536
elitism_idx = self.last_generation_elitism_indices[elitism_idx]
15381537
# Use the elitism's index to return its pre-calculated fitness value.
@@ -1544,8 +1543,7 @@ def cal_pop_fitness(self):
15441543
# Index of the parent in the 'self.last_generation_parents' array.
15451544
# This is not its index within the population. It is just its index in the 'self.last_generation_parents' array.
15461545
# parent_idx = numpy.where(numpy.all(self.last_generation_parents == sol, axis=1))[0][0]
1547-
parent_idx = last_generation_parents_as_list.index(
1548-
list(sol))
1546+
parent_idx = last_generation_parents_as_list.index(list(sol))
15491547
# Use the returned parent index to return its index in the last population.
15501548
parent_idx = self.last_generation_parents_indices[parent_idx]
15511549
# Use the parent's index to return its pre-calculated fitness value.
@@ -1573,13 +1571,11 @@ def cal_pop_fitness(self):
15731571
solutions_indices = numpy.where(
15741572
numpy.array(pop_fitness) == "undefined")[0]
15751573
# Number of batches.
1576-
num_batches = int(numpy.ceil(
1577-
len(solutions_indices) / self.fitness_batch_size))
1574+
num_batches = int(numpy.ceil(len(solutions_indices) / self.fitness_batch_size))
15781575
# For each batch, get its indices and call the fitness function.
15791576
for batch_idx in range(num_batches):
15801577
batch_first_index = batch_idx * self.fitness_batch_size
1581-
batch_last_index = (batch_idx + 1) * \
1582-
self.fitness_batch_size
1578+
batch_last_index = (batch_idx + 1) * self.fitness_batch_size
15831579
batch_indices = solutions_indices[batch_first_index:batch_last_index]
15841580
batch_solutions = self.population[batch_indices, :]
15851581

@@ -1660,17 +1656,15 @@ def cal_pop_fitness(self):
16601656
# Reaching this block means that batch processing is used. The fitness values are calculated in batches.
16611657

16621658
# Number of batches.
1663-
num_batches = int(numpy.ceil(
1664-
len(solutions_to_submit_indices) / self.fitness_batch_size))
1659+
num_batches = int(numpy.ceil(len(solutions_to_submit_indices) / self.fitness_batch_size))
16651660
# Each element of the `batches_solutions` list represents the solutions in one batch.
16661661
batches_solutions = []
16671662
# Each element of the `batches_indices` list represents the solutions' indices in one batch.
16681663
batches_indices = []
16691664
# For each batch, get its indices and call the fitness function.
16701665
for batch_idx in range(num_batches):
16711666
batch_first_index = batch_idx * self.fitness_batch_size
1672-
batch_last_index = (batch_idx + 1) * \
1673-
self.fitness_batch_size
1667+
batch_last_index = (batch_idx + 1) * self.fitness_batch_size
16741668
batch_indices = solutions_to_submit_indices[batch_first_index:batch_last_index]
16751669
batch_solutions = self.population[batch_indices, :]
16761670

‎pygad/utils/mutation.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,8 +438,39 @@ def adaptive_mutation_population_fitness(self, offspring):
438438

439439
fitness[:self.last_generation_parents.shape[0]] = self.last_generation_fitness[self.last_generation_parents_indices]
440440

441-
for idx in range(len(parents_to_keep), fitness.shape[0]):
442-
fitness[idx] = self.fitness_func(self, temp_population[idx], None)
441+
first_idx = len(parents_to_keep)
442+
last_idx = fitness.shape[0]
443+
fitness[first_idx:last_idx] = [0]*(last_idx - first_idx)
444+
445+
if self.fitness_batch_size in [1, None]:
446+
# Calculate the fitness for each individual solution.
447+
for idx in range(first_idx, last_idx):
448+
fitness[idx] = self.fitness_func(self,
449+
temp_population[idx],
450+
None)
451+
else:
452+
# Calculate the fitness for batch of solutions.
453+
454+
# Number of batches.
455+
num_batches = int(numpy.ceil((last_idx - first_idx) / self.fitness_batch_size))
456+
457+
for batch_idx in range(num_batches):
458+
# The index of the first solution in the current batch.
459+
batch_first_index = first_idx + batch_idx * self.fitness_batch_size
460+
# The index of the last solution in the current batch.
461+
if batch_idx == (num_batches - 1):
462+
batch_last_index = last_idx
463+
else:
464+
batch_last_index = first_idx + (batch_idx + 1) * self.fitness_batch_size
465+
466+
# Calculate the fitness values for the batch.
467+
fitness_temp = self.fitness_func(self,
468+
temp_population[batch_first_index:batch_last_index],
469+
None)
470+
# Insert the fitness of each solution at the proper index.
471+
for idx in range(batch_first_index, batch_last_index):
472+
fitness[idx] = fitness_temp[idx - batch_first_index]
473+
443474
average_fitness = numpy.mean(fitness)
444475

445476
return average_fitness, fitness[len(parents_to_keep):]

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /