Skip to content

Commit d06837b

Browse files
committed
Generate constrained random values
1 parent 33f443e commit d06837b

15 files changed

+213
-46
lines changed

example.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import pygad
2+
import numpy
3+
4+
function_inputs = [4,-2,3.5,5,-11,-4.7]
5+
desired_output = 44
6+
7+
def fitness_func(ga_instance, solution, solution_idx):
8+
output = numpy.sum(solution*function_inputs)
9+
fitness = 1.0 / (numpy.abs(output - desired_output) + 0.000001)
10+
return fitness
11+
12+
num_genes = len(function_inputs)
13+
14+
ga_instance = pygad.GA(num_generations=100,
15+
num_parents_mating=10,
16+
sol_per_pop=20,
17+
num_genes=num_genes,
18+
mutation_num_genes=6,
19+
fitness_func=fitness_func,
20+
# suppress_warnings=True,
21+
random_mutation_min_val=4,
22+
random_mutation_max_val=10,
23+
mutation_by_replacement=True,
24+
gene_type=int,
25+
# mutation_probability=0.4,
26+
gene_constraint=[lambda x: x[0]>=8,None,None,None,None,None])
27+
28+
ga_instance.run()
227 Bytes
Binary file not shown.
80.4 KB
Binary file not shown.
255 Bytes
Binary file not shown.
15.9 KB
Binary file not shown.

pygad/helper/unique.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,6 @@ def unique_genes_by_space(self,
316316
# Update the list of duplicate indices after each iteration.
317317
_, unique_gene_indices = numpy.unique(new_solution, return_index=True)
318318
not_unique_indices = set(range(len(new_solution))) - set(unique_gene_indices)
319-
# self.logger.info("not_unique_indices INSIDE", not_unique_indices)
320319

321320
return new_solution, not_unique_indices, num_unsolved_duplicates
322321

@@ -551,7 +550,7 @@ def find_two_duplicates(self,
551550
# This means there is no way to solve the duplicates between the genes.
552551
# Because the space of the duplicates genes only has a single value and there is no alternatives.
553552
return None, gene
554-
553+
555554
def unpack_gene_space(self,
556555
range_min,
557556
range_max,

pygad/pygad.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -564,24 +564,30 @@ def __init__(self,
564564
# Validate that gene_constraint is a list or tuple and every element inside it is either None or callable.
565565
if gene_constraint:
566566
if type(gene_constraint) in [list, tuple]:
567-
for constraint_idx, item in enumerate(gene_constraint):
568-
# Check whether the element is None or a callable.
569-
if item and callable(item):
570-
if item.__code__.co_argcount == 1:
571-
# Every callable is valid if it receives a single argument.
572-
# This argument represents the solution.
567+
if len(gene_constraint) == self.num_genes:
568+
for constraint_idx, item in enumerate(gene_constraint):
569+
# Check whether the element is None or a callable.
570+
if item is None:
573571
pass
572+
elif item and callable(item):
573+
if item.__code__.co_argcount == 1:
574+
# Every callable is valid if it receives a single argument.
575+
# This argument represents the solution.
576+
pass
577+
else:
578+
self.valid_parameters = False
579+
raise ValueError(f"Every callable inside the gene_constraint parameter must accept a single argument representing the solution/chromosome. But the callable at index {constraint_idx} named '{item.__code__.co_name}' accepts {item.__code__.co_argcount} argument(s).")
574580
else:
575581
self.valid_parameters = False
576-
raise ValueError(f"Every callable inside the gene_constraint parameter must accept a single argument representing the solution/chromosome. But the callable at index {constraint_idx} named '{item.__code__.co_name}' accepts {item.__code__.co_argcount} argument(s).")
577-
else:
578-
self.valid_parameters = False
579-
raise TypeError(f"The expected type of an element in the 'gene_constraint' parameter is None or a callable (e.g. function). But {item} at index {constraint_idx} of type {type(item)} found.")
582+
raise TypeError(f"The expected type of an element in the 'gene_constraint' parameter is None or a callable (e.g. function). But {item} at index {constraint_idx} of type {type(item)} found.")
583+
else:
584+
self.valid_parameters = False
585+
raise ValueError(f"The number of constrains ({len(gene_constraint)}) in the 'gene_constraint' parameter must be equal to the number of genes ({self.num_genes}).")
580586
else:
581587
self.valid_parameters = False
582-
raise TypeError(f"The expected type of the 'gene_constraint' parameter is either list or tuple. But the value {gene_constraint} of type {type(gene_constraint)} found.")
588+
raise TypeError(f"The expected type of the 'gene_constraint' parameter is either a list or tuple. But the value {gene_constraint} of type {type(gene_constraint)} found.")
583589
else:
584-
# It is None.
590+
# gene_constraint is None and not used.
585591
pass
586592

587593
self.gene_constraint = gene_constraint
354 Bytes
Binary file not shown.
Binary file not shown.
24.4 KB
Binary file not shown.
7.13 KB
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)