Skip to content

Commit b4bfb9a

Browse files
committed
Test adaptive mutation
1 parent b91a206 commit b4bfb9a

File tree

3 files changed

+273
-1
lines changed

3 files changed

+273
-1
lines changed

tests/test_adaptive_mutation.py

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
import pygad
2+
import random
3+
import numpy
4+
5+
num_generations = 1
6+
7+
initial_population = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
8+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
9+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
10+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
11+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
12+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
13+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
14+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
15+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
16+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]
17+
18+
def output_adaptive_mutation(gene_space=None,
19+
gene_type=float,
20+
num_genes=10,
21+
mutation_by_replacement=False,
22+
random_mutation_min_val=-1,
23+
random_mutation_max_val=1,
24+
init_range_low=-4,
25+
init_range_high=4,
26+
initial_population=None,
27+
mutation_probability=[0.2, 0.1],
28+
fitness_batch_size=None,
29+
mutation_type="adaptive"):
30+
31+
def fitness_func_single(ga, solution, idx):
32+
return random.random()
33+
34+
def fitness_func_batch(ga, soluions, idxs):
35+
return numpy.random.uniform(size=len(soluions))
36+
37+
if fitness_batch_size in [1, None]:
38+
fitness_func = fitness_func_single
39+
else:
40+
fitness_func = fitness_func_batch
41+
42+
ga_instance = pygad.GA(num_generations=num_generations,
43+
num_parents_mating=5,
44+
fitness_func=fitness_func,
45+
sol_per_pop=10,
46+
num_genes=num_genes,
47+
gene_space=gene_space,
48+
gene_type=gene_type,
49+
initial_population=initial_population,
50+
init_range_low=init_range_low,
51+
init_range_high=init_range_high,
52+
random_mutation_min_val=random_mutation_min_val,
53+
random_mutation_max_val=random_mutation_max_val,
54+
allow_duplicate_genes=True,
55+
mutation_by_replacement=mutation_by_replacement,
56+
save_solutions=True,
57+
mutation_probability=mutation_probability,
58+
mutation_type=mutation_type,
59+
suppress_warnings=True,
60+
fitness_batch_size=fitness_batch_size,
61+
random_seed=1)
62+
63+
ga_instance.run()
64+
65+
return None, ga_instance
66+
67+
def test_adaptive_mutation():
68+
result, ga_instance = output_adaptive_mutation()
69+
70+
# assert result == True
71+
72+
def test_adaptive_mutation_gene_space():
73+
result, ga_instance = output_adaptive_mutation(gene_space=range(10))
74+
75+
# assert result == True
76+
77+
def test_adaptive_mutation_int_gene_type():
78+
result, ga_instance = output_adaptive_mutation(gene_type=int)
79+
80+
# assert result == True
81+
82+
def test_adaptive_mutation_gene_space_gene_type():
83+
result, ga_instance = output_adaptive_mutation(gene_space={"low": 0, "high": 10},
84+
gene_type=[float, 2])
85+
86+
# assert result == True
87+
88+
def test_adaptive_mutation_nested_gene_space():
89+
result, ga_instance = output_adaptive_mutation(gene_space=[[0, 1, 2, 3, 4],
90+
numpy.arange(5, 10),
91+
range(10, 15),
92+
{"low": 15, "high": 20},
93+
{"low": 20, "high": 30, "step": 2},
94+
None,
95+
numpy.arange(30, 35),
96+
numpy.arange(35, 40),
97+
numpy.arange(40, 45),
98+
[45, 46, 47, 48, 49]])
99+
# assert result == True
100+
101+
def test_adaptive_mutation_nested_gene_type():
102+
result, ga_instance = output_adaptive_mutation(gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]])
103+
104+
# assert result == True
105+
106+
def test_adaptive_mutation_nested_gene_space_nested_gene_type():
107+
result, ga_instance = output_adaptive_mutation(gene_space=[[0, 1, 2, 3, 4],
108+
numpy.arange(5, 10),
109+
range(10, 15),
110+
{"low": 15, "high": 20},
111+
{"low": 20, "high": 30, "step": 2},
112+
None,
113+
numpy.arange(30, 35),
114+
numpy.arange(35, 40),
115+
numpy.arange(40, 45),
116+
[45, 46, 47, 48, 49]],
117+
gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]])
118+
119+
# assert result == True
120+
121+
def test_adaptive_mutation_initial_population():
122+
global initial_population
123+
result, ga_instance = output_adaptive_mutation(initial_population=initial_population)
124+
125+
# assert result == True
126+
127+
def test_adaptive_mutation_initial_population_nested_gene_type():
128+
global initial_population
129+
result, ga_instance = output_adaptive_mutation(initial_population=initial_population,
130+
gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]])
131+
132+
# assert result == True
133+
134+
def test_adaptive_mutation_fitness_batch_size_1():
135+
result, ga_instance = output_adaptive_mutation(fitness_batch_size=1)
136+
137+
def test_adaptive_mutation_fitness_batch_size_2():
138+
result, ga_instance = output_adaptive_mutation(fitness_batch_size=2)
139+
140+
def test_adaptive_mutation_fitness_batch_size_3():
141+
result, ga_instance = output_adaptive_mutation(fitness_batch_size=3)
142+
143+
def test_adaptive_mutation_fitness_batch_size_4():
144+
result, ga_instance = output_adaptive_mutation(fitness_batch_size=4)
145+
146+
def test_adaptive_mutation_fitness_batch_size_5():
147+
result, ga_instance = output_adaptive_mutation(fitness_batch_size=5)
148+
149+
def test_adaptive_mutation_fitness_batch_size_6():
150+
result, ga_instance = output_adaptive_mutation(fitness_batch_size=6)
151+
152+
def test_adaptive_mutation_fitness_batch_size_7():
153+
result, ga_instance = output_adaptive_mutation(fitness_batch_size=7)
154+
155+
def test_adaptive_mutation_fitness_batch_size_8():
156+
result, ga_instance = output_adaptive_mutation(fitness_batch_size=8)
157+
158+
def test_adaptive_mutation_fitness_batch_size_9():
159+
result, ga_instance = output_adaptive_mutation(fitness_batch_size=9)
160+
161+
def test_adaptive_mutation_fitness_batch_size_10():
162+
result, ga_instance = output_adaptive_mutation(fitness_batch_size=10)
163+
164+
if __name__ == "__main__":
165+
print()
166+
test_adaptive_mutation()
167+
print()
168+
169+
test_adaptive_mutation_int_gene_type()
170+
print()
171+
172+
test_adaptive_mutation_gene_space()
173+
print()
174+
175+
test_adaptive_mutation_gene_space_gene_type()
176+
print()
177+
178+
test_adaptive_mutation_nested_gene_space()
179+
print()
180+
181+
test_adaptive_mutation_nested_gene_type()
182+
print()
183+
184+
test_adaptive_mutation_initial_population()
185+
print()
186+
187+
test_adaptive_mutation_initial_population_nested_gene_type()
188+
print()
189+
190+
test_adaptive_mutation_fitness_batch_size_1()
191+
print()
192+
193+
test_adaptive_mutation_fitness_batch_size_1()
194+
print()
195+
196+
test_adaptive_mutation_fitness_batch_size_2()
197+
print()
198+
199+
test_adaptive_mutation_fitness_batch_size_3()
200+
print()
201+
202+
test_adaptive_mutation_fitness_batch_size_4()
203+
print()
204+
205+
test_adaptive_mutation_fitness_batch_size_5()
206+
print()
207+
208+
test_adaptive_mutation_fitness_batch_size_6()
209+
print()
210+
211+
test_adaptive_mutation_fitness_batch_size_7()
212+
print()
213+
214+
test_adaptive_mutation_fitness_batch_size_8()
215+
print()
216+
217+
test_adaptive_mutation_fitness_batch_size_9()
218+
print()
219+
220+
test_adaptive_mutation_fitness_batch_size_10()
221+
print()
222+

tests/test_gene_space.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ def number_respect_gene_space(gene_space=None,
3030
random_mutation_max_val=1,
3131
init_range_low=-4,
3232
init_range_high=4,
33+
mutation_type="random",
34+
mutation_percent_genes="default",
3335
initial_population=None):
3436

3537
def fitness_func(ga, solution, idx):
@@ -50,6 +52,8 @@ def fitness_func(ga, solution, idx):
5052
allow_duplicate_genes=True,
5153
mutation_by_replacement=mutation_by_replacement,
5254
save_solutions=True,
55+
mutation_type=mutation_type,
56+
mutation_percent_genes=mutation_percent_genes,
5357
suppress_warnings=True,
5458
random_seed=2)
5559

@@ -77,6 +81,7 @@ def fitness_func(ga, solution, idx):
7781
if val >= ga_instance.gene_space[gene_idx]["low"] and val < ga_instance.gene_space[gene_idx]["high"]:
7882
pass
7983
else:
84+
print(gene_idx, val, current_gene_space)
8085
num_outside += 1
8186
else:
8287
gene_space_values = numpy.arange(ga_instance.gene_space[gene_idx]["low"],
@@ -378,6 +383,43 @@ def test_nested_gene_space_mix_initial_population_single_gene_type():
378383

379384
assert num_outside == 0
380385

386+
def test_nested_gene_space_single_gene_type_adaptive_mutation():
387+
num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
388+
numpy.arange(0, 10),
389+
range(0, 10),
390+
{"low": 0, "high": 10},
391+
{"low": 0, "high": 10},
392+
range(0, 10),
393+
numpy.arange(0, 10),
394+
numpy.arange(0, 10),
395+
{"low": 0, "high": 10},
396+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]],
397+
# Due to rounding the genes, a gene at index 4 will have a value of 10 (outside the dict range) if [float, 2] is used.
398+
gene_type=[float, 4],
399+
mutation_percent_genes=[70, 50],
400+
mutation_type="adaptive")
401+
# print(ga_instance.population)
402+
403+
assert num_outside == 0
404+
405+
def test_nested_gene_space_nested_gene_type_adaptive_mutation():
406+
num_outside, ga_instance = number_respect_gene_space(gene_space=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
407+
numpy.arange(0, 10),
408+
range(0, 10),
409+
{"low": 0, "high": 10},
410+
{"low": 0, "high": 10},
411+
range(0, 10),
412+
numpy.arange(0, 10),
413+
numpy.arange(0, 10),
414+
{"low": 0, "high": 10},
415+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]],
416+
gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]],
417+
mutation_percent_genes=[70, 50],
418+
mutation_type="adaptive")
419+
# print(ga_instance.population)
420+
421+
assert num_outside == 0
422+
381423
if __name__ == "__main__":
382424
print()
383425
test_gene_space_range()
@@ -446,4 +488,10 @@ def test_nested_gene_space_mix_initial_population_single_gene_type():
446488
print()
447489

448490
test_nested_gene_space_mix_initial_population_single_gene_type()
449-
print()
491+
print()
492+
493+
test_nested_gene_space_single_gene_type_adaptive_mutation()
494+
print()
495+
496+
test_nested_gene_space_nested_gene_type_adaptive_mutation()
497+
print()

tests/test_number_fitness_function_calls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
sol_per_pop = 10
1010
num_parents_mating = 5
1111

12+
# TODO: Calculate the number when fitness_batch_size is used.
13+
1214
def number_calls_fitness_function(keep_elitism=1,
1315
keep_parents=-1,
1416
mutation_type="random",

0 commit comments

Comments
 (0)