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 2f139d3

Browse files
Fixes and more tests
1 parent 6b94152 commit 2f139d3

File tree

4 files changed

+345
-31
lines changed

4 files changed

+345
-31
lines changed

‎pygad/utils/mutation.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,13 @@ def mutation_by_space(self, offspring):
7575
elif type(curr_gene_space) is dict:
7676
# The gene's space of type dict specifies the lower and upper limits of a gene.
7777
if 'step' in curr_gene_space.keys():
78+
# The numpy.random.choice() and numpy.random.uniform() functions return a NumPy array as the output even if the array has a single value.
79+
# We have to return the output at index 0 to force a numeric value to be returned not an object of type numpy.ndarray.
80+
# If numpy.ndarray is returned, then it will cause an issue later while using the set() function.
7881
value_from_space = numpy.random.choice(numpy.arange(start=curr_gene_space['low'],
7982
stop=curr_gene_space['high'],
8083
step=curr_gene_space['step']),
81-
size=1)
84+
size=1)[0]
8285
else:
8386
value_from_space = numpy.random.uniform(low=curr_gene_space['low'],
8487
high=curr_gene_space['high'],
@@ -104,7 +107,7 @@ def mutation_by_space(self, offspring):
104107
value_from_space = numpy.random.choice(numpy.arange(start=self.gene_space['low'],
105108
stop=self.gene_space['high'],
106109
step=self.gene_space['step']),
107-
size=1)
110+
size=1)[0]
108111
else:
109112
value_from_space = numpy.random.uniform(low=self.gene_space['low'],
110113
high=self.gene_space['high'],
@@ -186,7 +189,7 @@ def mutation_probs_by_space(self, offspring):
186189
value_from_space = numpy.random.choice(numpy.arange(start=curr_gene_space['low'],
187190
stop=curr_gene_space['high'],
188191
step=curr_gene_space['step']),
189-
size=1)
192+
size=1)[0]
190193
else:
191194
value_from_space = numpy.random.uniform(low=curr_gene_space['low'],
192195
high=curr_gene_space['high'],
@@ -211,7 +214,7 @@ def mutation_probs_by_space(self, offspring):
211214
value_from_space = numpy.random.choice(numpy.arange(start=self.gene_space['low'],
212215
stop=self.gene_space['high'],
213216
step=self.gene_space['step']),
214-
size=1)
217+
size=1)[0]
215218
else:
216219
value_from_space = numpy.random.uniform(low=self.gene_space['low'],
217220
high=self.gene_space['high'],
@@ -520,10 +523,13 @@ def adaptive_mutation_by_space(self, offspring):
520523
elif type(curr_gene_space) is dict:
521524
# Selecting a value randomly from the current gene's space in the 'gene_space' attribute.
522525
if 'step' in curr_gene_space.keys():
526+
# The numpy.random.choice() and numpy.random.uniform() functions return a NumPy array as the output even if the array has a single value.
527+
# We have to return the output at index 0 to force a numeric value to be returned not an object of type numpy.ndarray.
528+
# If numpy.ndarray is returned, then it will cause an issue later while using the set() function.
523529
value_from_space = numpy.random.choice(numpy.arange(start=curr_gene_space['low'],
524530
stop=curr_gene_space['high'],
525531
step=curr_gene_space['step']),
526-
size=1)
532+
size=1)[0]
527533
else:
528534
value_from_space = numpy.random.uniform(low=curr_gene_space['low'],
529535
high=curr_gene_space['high'],
@@ -548,7 +554,7 @@ def adaptive_mutation_by_space(self, offspring):
548554
value_from_space = numpy.random.choice(numpy.arange(start=self.gene_space['low'],
549555
stop=self.gene_space['high'],
550556
step=self.gene_space['step']),
551-
size=1)
557+
size=1)[0]
552558
else:
553559
value_from_space = numpy.random.uniform(low=self.gene_space['low'],
554560
high=self.gene_space['high'],
@@ -699,7 +705,7 @@ def adaptive_mutation_probs_by_space(self, offspring):
699705
value_from_space = numpy.random.choice(numpy.arange(start=curr_gene_space['low'],
700706
stop=curr_gene_space['high'],
701707
step=curr_gene_space['step']),
702-
size=1)
708+
size=1)[0]
703709
else:
704710
value_from_space = numpy.random.uniform(low=curr_gene_space['low'],
705711
high=curr_gene_space['high'],
@@ -721,10 +727,13 @@ def adaptive_mutation_probs_by_space(self, offspring):
721727
# Selecting a value randomly from the global gene space in the 'gene_space' attribute.
722728
if type(self.gene_space) is dict:
723729
if 'step' in self.gene_space.keys():
730+
# The numpy.random.choice() and numpy.random.uniform() functions return a NumPy array as the output even if the array has a single value.
731+
# We have to return the output at index 0 to force a numeric value to be returned not an object of type numpy.ndarray.
732+
# If numpy.ndarray is returned, then it will cause an issue later while using the set() function.
724733
value_from_space = numpy.random.choice(numpy.arange(start=self.gene_space['low'],
725734
stop=self.gene_space['high'],
726735
step=self.gene_space['step']),
727-
size=1)
736+
size=1)[0]
728737
else:
729738
value_from_space = numpy.random.uniform(low=self.gene_space['low'],
730739
high=self.gene_space['high'],

‎tests/test_crossover_mutation.py

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
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_crossover_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+
crossover_probability=None,
28+
mutation_probability=None,
29+
crossover_type=None,
30+
mutation_type=None):
31+
32+
def fitness_func(ga, solution, idx):
33+
return random.random()
34+
35+
ga_instance = pygad.GA(num_generations=num_generations,
36+
num_parents_mating=5,
37+
fitness_func=fitness_func,
38+
sol_per_pop=10,
39+
num_genes=num_genes,
40+
gene_space=gene_space,
41+
gene_type=gene_type,
42+
initial_population=initial_population,
43+
init_range_low=init_range_low,
44+
init_range_high=init_range_high,
45+
random_mutation_min_val=random_mutation_min_val,
46+
random_mutation_max_val=random_mutation_max_val,
47+
allow_duplicate_genes=True,
48+
mutation_by_replacement=mutation_by_replacement,
49+
save_solutions=True,
50+
crossover_probability=crossover_probability,
51+
mutation_probability=mutation_probability,
52+
crossover_type=crossover_type,
53+
mutation_type=mutation_type,
54+
suppress_warnings=True,
55+
random_seed=1)
56+
57+
ga_instance.run()
58+
59+
comparison_result = []
60+
for solution_idx, solution in enumerate(ga_instance.population):
61+
if list(solution) in ga_instance.initial_population.tolist():
62+
comparison_result.append(True)
63+
else:
64+
comparison_result.append(False)
65+
66+
comparison_result = numpy.array(comparison_result)
67+
result = numpy.all(comparison_result == True)
68+
69+
print("Comparison result is {result}".format(result=result))
70+
return result, ga_instance
71+
72+
def test_no_crossover_no_mutation():
73+
result, ga_instance = output_crossover_mutation()
74+
75+
assert result == True
76+
77+
def test_no_crossover_no_mutation_gene_space():
78+
result, ga_instance = output_crossover_mutation(gene_space=range(10))
79+
80+
assert result == True
81+
82+
def test_no_crossover_no_mutation_int_gene_type():
83+
result, ga_instance = output_crossover_mutation(gene_type=int)
84+
85+
assert result == True
86+
87+
88+
def test_no_crossover_no_mutation_gene_space_gene_type():
89+
result, ga_instance = output_crossover_mutation(gene_space={"low": 0, "high": 10},
90+
gene_type=[float, 2])
91+
92+
assert result == True
93+
94+
95+
def test_no_crossover_no_mutation_nested_gene_space():
96+
result, ga_instance = output_crossover_mutation(gene_space=[[0, 1, 2, 3, 4],
97+
numpy.arange(5, 10),
98+
range(10, 15),
99+
{"low": 15, "high": 20},
100+
{"low": 20, "high": 30, "step": 2},
101+
None,
102+
numpy.arange(30, 35),
103+
numpy.arange(35, 40),
104+
numpy.arange(40, 45),
105+
[45, 46, 47, 48, 49]])
106+
assert result == True
107+
108+
def test_no_crossover_no_mutation_nested_gene_type():
109+
result, ga_instance = output_crossover_mutation(gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]])
110+
111+
assert result == True
112+
113+
def test_no_crossover_no_mutation_nested_gene_space_nested_gene_type():
114+
result, ga_instance = output_crossover_mutation(gene_space=[[0, 1, 2, 3, 4],
115+
numpy.arange(5, 10),
116+
range(10, 15),
117+
{"low": 15, "high": 20},
118+
{"low": 20, "high": 30, "step": 2},
119+
None,
120+
numpy.arange(30, 35),
121+
numpy.arange(35, 40),
122+
numpy.arange(40, 45),
123+
[45, 46, 47, 48, 49]],
124+
gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]])
125+
126+
assert result == True
127+
128+
def test_no_crossover_no_mutation_initial_population():
129+
global initial_population
130+
result, ga_instance = output_crossover_mutation(initial_population=initial_population)
131+
132+
assert result == True
133+
134+
def test_no_crossover_no_mutation_initial_population_nested_gene_type():
135+
global initial_population
136+
result, ga_instance = output_crossover_mutation(initial_population=initial_population,
137+
gene_type=[int, float, numpy.float64, [float, 3], [float, 4], numpy.int16, [numpy.float32, 1], int, float, [float, 3]])
138+
139+
assert result == True
140+
141+
def test_crossover_no_mutation_zero_crossover_probability():
142+
global initial_population
143+
result, ga_instance = output_crossover_mutation(crossover_type="single_point",
144+
crossover_probability=0.0)
145+
146+
assert result == True
147+
148+
def test_zero_crossover_probability_zero_mutation_probability():
149+
global initial_population
150+
result, ga_instance = output_crossover_mutation(crossover_type="single_point",
151+
crossover_probability=0.0,
152+
mutation_type="random",
153+
mutation_probability=0.0)
154+
155+
assert result == True
156+
157+
if __name__ == "__main__":
158+
print()
159+
test_no_crossover_no_mutation()
160+
print()
161+
162+
test_no_crossover_no_mutation_int_gene_type()
163+
print()
164+
165+
test_no_crossover_no_mutation_gene_space()
166+
print()
167+
168+
test_no_crossover_no_mutation_gene_space_gene_type()
169+
print()
170+
171+
test_no_crossover_no_mutation_nested_gene_space()
172+
print()
173+
174+
test_no_crossover_no_mutation_nested_gene_type()
175+
print()
176+
177+
test_no_crossover_no_mutation_initial_population()
178+
print()
179+
180+
test_no_crossover_no_mutation_initial_population_nested_gene_type()
181+
print()
182+
183+
test_crossover_no_mutation_zero_crossover_probability()
184+
print()
185+
186+
test_zero_crossover_probability_zero_mutation_probability()
187+
print()
188+

0 commit comments

Comments
(0)

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