Skip to content

Commit ae360db

Browse files
authored
New parameter added: delay_after_gen
1. A new parameter named `delay_after_gen` is added in PyGAD 2.4.0. It accepts a non-negative number specifying the number of seconds to wait after a generation completes and before going to the next generation. It defaults to 0.0 which means no delay after the generation. 2. If the function passed to the `callback_generation` parameter returned "stop", then the run() method stops without completing the generations.
1 parent e21cde6 commit ae360db

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

pygad.py

+19-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import random
33
import matplotlib.pyplot
44
import pickle
5+
import time
56

67
class GA:
78
def __init__(self,
@@ -23,7 +24,8 @@ def __init__(self,
2324
mutation_num_genes=None,
2425
random_mutation_min_val=-1.0,
2526
random_mutation_max_val=1.0,
26-
callback_generation=None):
27+
callback_generation=None,
28+
delay_after_gen=0.0):
2729

2830
"""
2931
The constructor of the GA class accepts all parameters required to create an instance of the GA class. It validates such parameters.
@@ -55,7 +57,9 @@ def __init__(self,
5557
random_mutation_min_val: The minimum value of the range from which a random value is selected to be added to the selected gene(s) to mutate. It defaults to -1.0.
5658
random_mutation_max_val: The maximum value of the range from which a random value is selected to be added to the selected gene(s) to mutate. It defaults to 1.0.
5759
58-
callback_generation: If not None, then it accepts a function to be called after each generation. This function must accept a single parameter representing the instance of the genetic algorithm.
60+
callback_generation: If not None, then it accepts a function to be called after each generation. This function must accept a single parameter representing the instance of the genetic algorithm. If the function returned "stop", then the run() method stops without completing the generations.
61+
62+
delay_after_gen: Added in PyGAD 2.4.0. It accepts a non-negative number specifying the number of seconds to wait after a generation completes and before going to the next generation. It defaults to 0.0 which means no delay after the generation.
5963
"""
6064

6165
self.init_range_low = init_range_low
@@ -216,7 +220,7 @@ def __init__(self,
216220
raise ValueError("The fitness function must accept 2 parameters representing the solution to which the fitness value is calculated and the solution index within the population.\nThe passed fitness function named '{funcname}' accepts {argcount} argument(s).".format(funcname=fitness_func.__code__.co_name, argcount=fitness_func.__code__.co_argcount))
217221
else:
218222
self.valid_parameters = False
219-
raise ValueError("The value assigned to the 'fitness_func' parameter is expected to be of type function by {fitness_func_type} found.".format(fitness_func_type=type(fitness_func)))
223+
raise ValueError("The value assigned to the 'fitness_func' parameter is expected to be of type function but {fitness_func_type} found.".format(fitness_func_type=type(fitness_func)))
220224

221225
# Check if the callback_generation exists.
222226
if not (callback_generation is None):
@@ -230,10 +234,16 @@ def __init__(self,
230234
raise ValueError("The callback_generation function must accept only 1 parameter representing the instance of the genetic algorithm.\nThe passed callback_generation function named '{funcname}' accepts {argcount} argument(s).".format(funcname=callback_generation.__code__.co_name, argcount=callback_generation.__code__.co_argcount))
231235
else:
232236
self.valid_parameters = False
233-
raise ValueError("The value assigned to the 'callback_generation' parameter is expected to be of type function by {callback_generation_type} found.".format(callback_generation_type=type(callback_generation)))
237+
raise ValueError("The value assigned to the 'callback_generation' parameter is expected to be of type function but {callback_generation_type} found.".format(callback_generation_type=type(callback_generation)))
234238
else:
235239
self.callback_generation = None
236240

241+
if delay_after_gen >= 0.0:
242+
self.delay_after_gen = delay_after_gen
243+
else:
244+
self.valid_parameters = False
245+
raise ValueError("The value passed to the 'delay_after_gen' parameter must be a non-negative number. The value passed is {delay_after_gen} of type {delay_after_gen_type}.".format(delay_after_gen=delay_after_gen, delay_after_gen_type=type(delay_after_gen)))
246+
237247
# The number of completed generations.
238248
self.generations_completed = 0
239249

@@ -352,7 +362,11 @@ def run(self):
352362

353363
# If the callback_generation attribute is not None, then cal the callback function after the generation.
354364
if not (self.callback_generation is None):
355-
self.callback_generation(self)
365+
r = self.callback_generation(self)
366+
if type(r) is str and r.lower() == "stop":
367+
break
368+
369+
time.sleep(self.delay_after_gen)
356370

357371
self.best_solution_generation = numpy.where(numpy.array(self.best_solutions_fitness) == numpy.max(numpy.array(self.best_solutions_fitness)))[0][0]
358372
# After the run() method completes, the run_completed flag is changed from False to True.

0 commit comments

Comments
 (0)