Skip to content

Commit

Permalink
More updates
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmedfgad committed Jun 14, 2023
1 parent 83a1635 commit 31a3975
Show file tree
Hide file tree
Showing 7 changed files with 451 additions and 142 deletions.
12 changes: 8 additions & 4 deletions pygad/helper/unique.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,11 +603,15 @@ def find_two_duplicates(self,
return None, gene

def unpack_gene_space(self,
range_min,
range_max,
num_values_from_inf_range=100):
"""
Unpack the gene_space for the purpose of selecting a value that solves the duplicates.
This is by replacing each range by a list of values.
It accepts:
range_min: The range minimum value.
range_min: The range maximum value.
num_values_from_inf_range: For infinite range of float values, a fixed number of values equal to num_values_from_inf_range is selected using the numpy.linspace() function.
It returns the unpacked gene space.
"""
Expand Down Expand Up @@ -662,8 +666,8 @@ def unpack_gene_space(self,
gene_space_unpacked[space_idx] = [space]
elif space is None:
# Randomly generate the value using the mutation range.
gene_space_unpacked[space_idx] = numpy.arange(start=self.random_mutation_min_val,
stop=self.random_mutation_max_val)
gene_space_unpacked[space_idx] = numpy.arange(start=range_min,
stop=range_max)
elif type(space) is range:
# Convert the range to a list.
gene_space_unpacked[space_idx] = list(space)
Expand Down Expand Up @@ -720,8 +724,8 @@ def unpack_gene_space(self,
none_indices = numpy.where(numpy.array(gene_space_unpacked[space_idx]) == None)[0]
if len(none_indices) > 0:
for idx in none_indices:
random_value = numpy.random.uniform(low=self.random_mutation_min_val,
high=self.random_mutation_max_val,
random_value = numpy.random.uniform(low=range_min,
high=range_max,
size=1)[0]
gene_space_unpacked[space_idx][idx] = random_value

Expand Down
4 changes: 2 additions & 2 deletions pygad/kerasga/kerasga.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ def model_weights_as_matrix(model, weights_vector):

return weights_matrix

def predict(model, solution, data):
def predict(model, solution, data, verbose=1):
# Fetch the parameters of the best solution.
solution_weights = model_weights_as_matrix(model=model,
weights_vector=solution)
_model = tensorflow.keras.models.clone_model(model)
_model.set_weights(solution_weights)
predictions = _model.predict(data)
predictions = _model(data)

return predictions

Expand Down
240 changes: 177 additions & 63 deletions pygad/pygad.py

Large diffs are not rendered by default.

122 changes: 92 additions & 30 deletions pygad/utils/mutation.py

Large diffs are not rendered by default.

29 changes: 25 additions & 4 deletions tests/test_crossover_mutation.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ def test_random_mutation_manual_call2():
# assert comp_sorted[0] == 0

def test_random_mutation_manual_call3():
# Use random_mutation_min_val & random_mutation_max_val as numbers.
random_mutation_min_val = 888
random_mutation_max_val = 999
result, ga_instance = output_crossover_mutation(mutation_type="random",
Expand All @@ -204,14 +205,31 @@ def test_random_mutation_manual_call3():
comp_sorted = sorted(comp.copy())
comp_sorted = numpy.abs(numpy.unique(comp))

# The other 1 added to include the last value in the range.
# assert len(comp_sorted) in range(1, 1 + 1 + ga_instance.mutation_num_genes)
# assert comp_sorted[0] == 0

value_space = list(range(random_mutation_min_val, random_mutation_max_val))
for value in comp_sorted:
assert value in value_space

def test_random_mutation_manual_call4():
# Use random_mutation_min_val & random_mutation_max_val as lists.
random_mutation_min_val = [888]*10
random_mutation_max_val = [999]*10
result, ga_instance = output_crossover_mutation(mutation_type="random",
random_mutation_min_val=random_mutation_min_val,
random_mutation_max_val=random_mutation_max_val,
mutation_by_replacement=True)
ga_instance.mutation_num_genes = 10

temp_offspring = numpy.array(initial_population[0:1])
offspring = ga_instance.random_mutation(offspring=temp_offspring.copy())

comp = offspring
comp_sorted = sorted(comp.copy())
comp_sorted = numpy.abs(numpy.unique(comp))

value_space = list(range(random_mutation_min_val[0], random_mutation_max_val[0]))
for value in comp_sorted:
assert value in value_space

if __name__ == "__main__":
print()
test_no_crossover_no_mutation()
Expand Down Expand Up @@ -253,3 +271,6 @@ def test_random_mutation_manual_call3():
test_random_mutation_manual_call3()
print()

test_random_mutation_manual_call4()
print()

120 changes: 114 additions & 6 deletions tests/test_gene_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,37 @@ def fitness_func(ga, solution, idx):
num_outside = 0
if ga_instance.gene_space_nested == True:
for gene_idx in range(ga_instance.num_genes):

if type(ga_instance.init_range_low) in ga_instance.supported_int_float_types:
range_min_init = ga_instance.init_range_low
range_max_init = ga_instance.init_range_high
else:
range_min_init = ga_instance.init_range_low[gene_idx]
range_max_init = ga_instance.init_range_high[gene_idx]
if type(ga_instance.random_mutation_min_val) in ga_instance.supported_int_float_types:
range_min_mutation = ga_instance.random_mutation_min_val
range_max_mutation = ga_instance.random_mutation_max_val
else:
range_min_mutation = ga_instance.random_mutation_min_val[gene_idx]
range_max_mutation = ga_instance.random_mutation_max_val[gene_idx]

all_gene_values = ga_instance.solutions[:, gene_idx]
if type(ga_instance.gene_space[gene_idx]) in [list, tuple, range, numpy.ndarray]:
current_gene_space = list(ga_instance.gene_space[gene_idx])
for val in all_gene_values:
if val in current_gene_space:
# print(val, current_gene_space)
# print("current_gene_space", current_gene_space)
for val_idx, val in enumerate(all_gene_values):
if None in current_gene_space:
if (val in current_gene_space) or (val >= range_min_init and val < range_max_init) or (val >= range_min_mutation and val < range_max_mutation):
pass
else:
# print("###########")
# print(gene_idx, val)
# print(current_gene_space)
# print(range_min_mutation, range_max_mutation)
# print("\n\n")
num_outside += 1
elif val in current_gene_space:
# print("val, current_gene_space", val, current_gene_space)
pass
else:
# print(gene_idx, val, current_gene_space)
Expand Down Expand Up @@ -98,14 +123,51 @@ def fitness_func(ga, solution, idx):
pass
else:
num_outside += 1
elif ga_instance.gene_space[gene_idx] is None:
for val in all_gene_values:
# print(val)
if (val >= range_min_init and val < range_max_init) or (val >= range_min_mutation and val < range_max_mutation):
pass
else:
# print("###########")
# print(gene_idx, val)
# print(ga_instance.gene_space[gene_idx])
# print(range_min_init, range_max_init)
# print(range_min_mutation, range_max_mutation)
# print("\n\n")
num_outside += 1
else:
for gene_idx in range(ga_instance.num_genes):

if type(ga_instance.init_range_low) in ga_instance.supported_int_float_types:
range_min_init = ga_instance.init_range_low
range_max_init = ga_instance.init_range_high
else:
range_min_init = ga_instance.init_range_low[gene_idx]
range_max_init = ga_instance.init_range_high[gene_idx]
if type(ga_instance.random_mutation_min_val) in ga_instance.supported_int_float_types:
range_min_mutation = ga_instance.random_mutation_min_val
range_max_mutation = ga_instance.random_mutation_max_val
else:
range_min_mutation = ga_instance.random_mutation_min_val[gene_idx]
range_max_mutation = ga_instance.random_mutation_max_val[gene_idx]

all_gene_values = ga_instance.solutions[:, gene_idx]
# print("all_gene_values", gene_idx, all_gene_values)
if type(ga_instance.gene_space) in [list, tuple, range, numpy.ndarray]:
current_gene_space = list(ga_instance.gene_space)
for val in all_gene_values:
if val in current_gene_space:
if None in current_gene_space:
if (val in current_gene_space) or (val >= range_min_init and val < range_max_init) or (val >= range_min_mutation and val < range_max_mutation):
pass
else:
# print("###########")
# print(gene_idx, val)
# print(current_gene_space)
# print(range_min_mutation, range_max_mutation)
# print("\n\n")
num_outside += 1
elif val in current_gene_space:
pass
else:
num_outside += 1
Expand Down Expand Up @@ -144,6 +206,11 @@ def test_gene_space_list():

assert num_outside == 0

def test_gene_space_list_None():
num_outside, _ = number_respect_gene_space(gene_space=[30, None, 40, 50, None, 60, 70, None, None, None])

assert num_outside == 0

def test_gene_space_numpy():
num_outside, _ = number_respect_gene_space(gene_space=numpy.array(list(range(10))))

Expand Down Expand Up @@ -318,6 +385,38 @@ def test_nested_gene_space_list2():

assert num_outside == 0

def test_nested_gene_space_list3_None():
num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, None],
[1, 2],
[2, None],
[3, 4],
[None, 5],
None,
[None, 7],
[None, None],
[8, 9],
None],
mutation_by_replacement=True)

assert num_outside == 0

def test_nested_gene_space_list4_None_custom_mutation_range():
num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, None],
[1, 2],
[2, None],
[3, 4],
[None, 5],
None,
[None, 7],
[None, None],
[8, 9],
None],
random_mutation_min_val=20,
random_mutation_max_val=40,
mutation_by_replacement=True)

assert num_outside == 0

def test_nested_gene_space_mix():
num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1, 2, 3, 4],
numpy.arange(5, 10),
Expand All @@ -329,7 +428,8 @@ def test_nested_gene_space_mix():
numpy.arange(35, 40),
numpy.arange(40, 45),
[45, 46, 47, 48, 49]],
gene_type=int)
gene_type=int,
mutation_by_replacement=True)

assert num_outside == 0

Expand All @@ -344,7 +444,7 @@ def test_nested_gene_space_mix_nested_gene_type():
numpy.arange(35, 40),
numpy.arange(40, 45),
[45, 46, 47, 48, 49]],
gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]])
gene_type=[int, float, numpy.float64, [float, 3], int, numpy.int16, [numpy.float32, 1], int, float, [float, 3]])
# print(ga_instance.population)

assert num_outside == 0
Expand Down Expand Up @@ -434,6 +534,8 @@ def test_nested_gene_space_nested_gene_type_adaptive_mutation():

test_gene_space_list()
print()
test_gene_space_list_None()
print()
test_gene_space_list_nested_gene_type()
print()

Expand Down Expand Up @@ -478,6 +580,12 @@ def test_nested_gene_space_nested_gene_type_adaptive_mutation():
test_nested_gene_space_list2()
print()

test_nested_gene_space_list3_None()
print()

test_nested_gene_space_list4_None_custom_mutation_range()
print()

test_nested_gene_space_mix()
print()

Expand Down
66 changes: 33 additions & 33 deletions tests/test_gene_space_allow_duplicate_genes.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,39 +379,39 @@ def test_nested_gene_space_mix_initial_population_single_gene_type():
assert num_outside == 0

if __name__ == "__main__":
# print()
# test_gene_space_range()
# print()
# test_gene_space_range_nested_gene_type()
# print()

# test_gene_space_numpy_arange()
# print()
# test_gene_space_numpy_arange_nested_gene_type()
# print()

# test_gene_space_list()
# print()
# test_gene_space_list_nested_gene_type()
# print()

# test_gene_space_list_single_value()
# print()
# test_gene_space_list_single_value_nested_gene_type()
# print()

# test_gene_space_numpy()
# print()
# test_gene_space_numpy_nested_gene_type()
# print()

# test_gene_space_dict_without_step()
# print()
# test_gene_space_dict_without_step_nested_gene_type()
# print()

# test_gene_space_dict_with_step()
# print()
print()
test_gene_space_range()
print()
test_gene_space_range_nested_gene_type()
print()

test_gene_space_numpy_arange()
print()
test_gene_space_numpy_arange_nested_gene_type()
print()

test_gene_space_list()
print()
test_gene_space_list_nested_gene_type()
print()

test_gene_space_list_single_value()
print()
test_gene_space_list_single_value_nested_gene_type()
print()

test_gene_space_numpy()
print()
test_gene_space_numpy_nested_gene_type()
print()

test_gene_space_dict_without_step()
print()
test_gene_space_dict_without_step_nested_gene_type()
print()

test_gene_space_dict_with_step()
print()
test_gene_space_dict_with_step_nested_gene_type()
print()

Expand Down

0 comments on commit 31a3975

Please sign in to comment.