You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: pygad/pygad.py
+32-4Lines changed: 32 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -49,6 +49,7 @@ def __init__(self,
49
49
random_mutation_min_val=-1.0,
50
50
random_mutation_max_val=1.0,
51
51
gene_space=None,
52
+
gene_constraint=None,
52
53
allow_duplicate_genes=True,
53
54
on_start=None,
54
55
on_fitness=None,
@@ -104,6 +105,8 @@ def __init__(self,
104
105
105
106
gene_space: It accepts a list of all possible values of the gene. This list is used in the mutation step. Should be used only if the gene space is a set of discrete values. No need for the 2 parameters (random_mutation_min_val and random_mutation_max_val) if the parameter gene_space exists. Added in PyGAD 2.5.0. In PyGAD 2.11.0, the gene_space can be assigned a dict.
106
107
108
+
gene_constraint: It accepts a list of constraints for the genes. Each constraint is a Python function. Added in PyGAD 3.5.0.
109
+
107
110
on_start: Accepts a function/method to be called only once before the genetic algorithm starts its evolution. If function, then it must accept a single parameter representing the instance of the genetic algorithm. If method, then it must accept 2 parameters where the second one refers to the method's object. Added in PyGAD 2.6.0.
108
111
on_fitness: Accepts a function/method to be called after calculating the fitness values of all solutions in the population. If function, then it must accept 2 parameters: 1) a list of all solutions' fitness values 2) the instance of the genetic algorithm. If method, then it must accept 3 parameters where the third one refers to the method's object. Added in PyGAD 2.6.0.
109
112
on_parents: Accepts a function/method to be called after selecting the parents that mates. If function, then it must accept 2 parameters: the first one represents the instance of the genetic algorithm and the second one represents the selected parents. If method, then it must accept 3 parameters where the third one refers to the method's object. Added in PyGAD 2.6.0.
# Check whether the element is None or a callable.
569
+
ifitemandcallable(item):
570
+
ifitem.__code__.co_argcount==1:
571
+
# Every callable is valid if it receives a single argument.
572
+
# This argument represents the solution.
573
+
pass
574
+
else:
575
+
self.valid_parameters=False
576
+
raiseValueError(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
+
raiseTypeError(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.")
580
+
else:
581
+
self.valid_parameters=False
582
+
raiseTypeError(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.")
583
+
else:
584
+
# It is None.
585
+
pass
586
+
587
+
self.gene_constraint=gene_constraint
588
+
561
589
# Validating the number of parents to be selected for mating (num_parents_mating)
562
590
ifnum_parents_mating<=0:
563
591
self.valid_parameters=False
564
592
raiseValueError(f"The number of parents mating (num_parents_mating) parameter must be > 0 but ({num_parents_mating}) found. \nThe following parameters must be > 0: \n1) Population size (i.e. number of solutions per population) (sol_per_pop).\n2) Number of selected parents in the mating pool (num_parents_mating).\n")
565
593
566
594
# Validating the number of parents to be selected for mating: num_parents_mating
567
-
if(num_parents_mating>self.sol_per_pop):
595
+
ifnum_parents_mating>self.sol_per_pop:
568
596
self.valid_parameters=False
569
597
raiseValueError(f"The number of parents to select for mating ({num_parents_mating}) cannot be greater than the number of solutions in the population ({self.sol_per_pop}) (i.e., num_parents_mating must always be <= sol_per_pop).\n")
570
598
571
599
self.num_parents_mating=num_parents_mating
572
600
573
601
# crossover: Refers to the method that applies the crossover operator based on the selected type of crossover in the crossover_type property.
574
602
# Validating the crossover type: crossover_type
575
-
if(crossover_typeisNone):
603
+
ifcrossover_typeisNone:
576
604
self.crossover=None
577
605
elifinspect.ismethod(crossover_type):
578
606
# Check if the crossover_type is a method that accepts 4 paramaters.
579
-
if(crossover_type.__code__.co_argcount==4):
607
+
ifcrossover_type.__code__.co_argcount==4:
580
608
# The crossover method assigned to the crossover_type parameter is validated.
581
609
self.crossover=crossover_type
582
610
else:
583
611
self.valid_parameters=False
584
612
raiseValueError(f"When 'crossover_type' is assigned to a method, then this crossover method must accept 4 parameters:\n1) Expected to be the 'self' object.\n2) The selected parents.\n3) The size of the offspring to be produced.\n4) The instance from the pygad.GA class.\n\nThe passed crossover method named '{crossover_type.__code__.co_name}' accepts {crossover_type.__code__.co_argcount} parameter(s).")
585
613
elifcallable(crossover_type):
586
614
# Check if the crossover_type is a function that accepts 2 paramaters.
587
-
if(crossover_type.__code__.co_argcount==3):
615
+
ifcrossover_type.__code__.co_argcount==3:
588
616
# The crossover function assigned to the crossover_type parameter is validated.
0 commit comments