@@ -432,9 +432,7 @@ def __init__(self,
432432
433433 # Number of solutions in the population.
434434 self .sol_per_pop = sol_per_pop
435- self .initialize_population (low = self .init_range_low ,
436- high = self .init_range_high ,
437- allow_duplicate_genes = allow_duplicate_genes ,
435+ self .initialize_population (allow_duplicate_genes = allow_duplicate_genes ,
438436 mutation_by_replacement = True ,
439437 gene_type = self .gene_type ,
440438 gene_constraint = gene_constraint )
@@ -457,32 +455,7 @@ def __init__(self,
457455 self .valid_parameters = False
458456 raise TypeError (f"The values in the initial population can be integers or floats but the value ({ initial_population [row_idx ][col_idx ]} ) of type { type (initial_population [row_idx ][col_idx ])} found." )
459457
460- # Forcing the initial_population array to have the data type assigned to the gene_type parameter.
461- if self .gene_type_single == True :
462- if self .gene_type [1 ] == None :
463- self .initial_population = numpy .array (initial_population ,
464- dtype = self .gene_type [0 ])
465- else :
466- # This block is reached only for non-integer data types (i.e. float).
467- self .initial_population = numpy .round (numpy .array (initial_population ,
468- dtype = self .gene_type [0 ]),
469- self .gene_type [1 ])
470- else :
471- initial_population = numpy .array (initial_population )
472- self .initial_population = numpy .zeros (shape = (initial_population .shape [0 ],
473- initial_population .shape [1 ]),
474- dtype = object )
475- for gene_idx in range (initial_population .shape [1 ]):
476- if self .gene_type [gene_idx ][1 ] is None :
477- self .initial_population [:, gene_idx ] = numpy .asarray (initial_population [:, gene_idx ],
478- dtype = self .gene_type [gene_idx ][0 ])
479- else :
480- # This block is reached only for non-integer data types (i.e. float).
481- self .initial_population [:, gene_idx ] = numpy .round (numpy .asarray (initial_population [:, gene_idx ],
482- dtype = self .gene_type [gene_idx ][0 ]),
483- self .gene_type [gene_idx ][1 ])
484-
485- # Check if duplicates are allowed. If not, then solve any exisiting duplicates in the passed initial population.
458+ # Check if duplicates are allowed. If not, then solve any existing duplicates in the passed initial population.
486459 if self .allow_duplicate_genes == False :
487460 for initial_solution_idx , initial_solution in enumerate (self .initial_population ):
488461 if self .gene_space is None :
@@ -497,6 +470,9 @@ def __init__(self,
497470 gene_type = self .gene_type ,
498471 num_trials = 10 )
499472
473+ # Change the data type and round all genes within the initial population.
474+ self .initial_population = self .change_population_dtype_and_round (initial_population )
475+
500476 # A NumPy array holding the initial population.
501477 self .population = self .initial_population .copy ()
502478 # Number of genes in the solution.
@@ -506,9 +482,9 @@ def __init__(self,
506482 # The population size.
507483 self .pop_size = (self .sol_per_pop , self .num_genes )
508484
509- # Round initial_population and population
510- self .initial_population = self .round_genes (self .initial_population )
511- self .population = self .round_genes ( self . population )
485+ # Change the data type and round all genes within the initial population.
486+ self .initial_population = self .change_population_dtype_and_round (self .initial_population )
487+ self .population = self .initial_population . copy ( )
512488
513489 # In case the 'gene_space' parameter is nested, then make sure the number of its elements equals to the number of genes.
514490 if self .gene_space_nested :
@@ -1375,8 +1351,6 @@ def round_genes(self, solutions):
13751351 return solutions
13761352
13771353 def initialize_population (self ,
1378- low ,
1379- high ,
13801354 allow_duplicate_genes ,
13811355 mutation_by_replacement ,
13821356 gene_type ,
@@ -1385,8 +1359,6 @@ def initialize_population(self,
13851359 Creates an initial population randomly as a NumPy array. The array is saved in the instance attribute named 'population'.
13861360
13871361 It accepts:
1388- -low: The lower value of the random range from which the gene values in the initial population are selected. It defaults to -4. Available in PyGAD 1.0.20 and higher.
1389- -high: The upper value of the random range from which the gene values in the initial population are selected. It defaults to -4. Available in PyGAD 1.0.20.
13901362 -allow_duplicate_genes: Whether duplicate genes are allowed or not.
13911363 -mutation_by_replacement: Whether mutation by replacement is enabled or not.
13921364 -gene_type: The data type of the genes.
@@ -1403,39 +1375,31 @@ def initialize_population(self,
14031375 self .pop_size = (self .sol_per_pop , self .num_genes )
14041376
14051377 if self .gene_space is None :
1406- # Creating the initial population randomly.
1407- if self .gene_type_single == True :
1408- # A NumPy array holding the initial population.
1409- self .population = numpy .asarray (numpy .random .uniform (low = low ,
1410- high = high ,
1411- size = self .pop_size ),
1412- dtype = self .gene_type [0 ])
1413- else :
1414- # Create an empty population of dtype=object to support storing mixed data types within the same array.
1415- self .population = numpy .zeros (
1416- shape = self .pop_size , dtype = object )
1417- # Loop through the genes, randomly generate the values of a single gene across the entire population, and add the values of each gene to the population.
1418- for gene_idx in range (self .num_genes ):
1378+ # Create the initial population randomly.
14191379
1420- range_min , range_max = self .get_initial_population_range (gene_index = gene_idx )
1380+ # Create an empty population.
1381+ self .population = numpy .zeros (shape = self .pop_size )
1382+
1383+ # Loop through the genes, randomly generate the values of a single gene across the entire population, and add the values of each gene to the population.
1384+ for gene_idx in range (self .num_genes ):
1385+ range_min , range_max = self .get_initial_population_range (gene_index = gene_idx )
14211386
1422- # A vector of all values of this single gene across all solutions in the population.
1423- gene_values = numpy .asarray (numpy .random .uniform (low = range_min ,
1424- high = range_max ,
1425- size = self .pop_size [0 ]),
1426- dtype = self .gene_type [gene_idx ][0 ])
1427- # Adding the current gene values to the population.
1428- self .population [:, gene_idx ] = gene_values
1387+ # A vector of all values of this single gene across all solutions in the population.
1388+ gene_values = numpy .random .uniform (low = range_min ,
1389+ high = range_max ,
1390+ size = self .pop_size [0 ])
1391+ # Adding the current gene values to the population.
1392+ self .population [:, gene_idx ] = gene_values
14291393
1430- # Round the randomly generated values .
1431- self .population = self .round_genes (self .population )
1394+ # Change the data type and round all genes within the initial population .
1395+ self .population = self .change_population_dtype_and_round (self .population )
14321396
14331397 # Enforce the gene constraints as much as possible.
14341398 if gene_constraint is None :
14351399 pass
14361400 else :
14371401 # Note that gene_constraint is not validated yet.
1438- # We have to set it as a propery of the pygad.GA instance to retrieve without passing it as an additional parameter.
1402+ # We have to set it as a property of the pygad.GA instance to retrieve without passing it as an additional parameter.
14391403 self .gene_constraint = gene_constraint
14401404 for sol_idx , solution in enumerate (self .population ):
14411405 for gene_idx in range (self .num_genes ):
@@ -1461,12 +1425,11 @@ def initialize_population(self,
14611425 for solution_idx in range (self .population .shape [0 ]):
14621426 # self.logger.info("Before", self.population[solution_idx])
14631427 self .population [solution_idx ], _ , _ = self .solve_duplicate_genes_randomly (solution = self .population [solution_idx ],
1464- min_val = low ,
1465- max_val = high ,
1428+ min_val = self . init_range_low ,
1429+ max_val = self . init_range_high ,
14661430 mutation_by_replacement = True ,
14671431 gene_type = gene_type ,
14681432 sample_size = 100 )
1469- # self.logger.info("After", self.population[solution_idx])
14701433
14711434 elif self .gene_space_nested :
14721435 if self .gene_type_single == True :
@@ -1482,13 +1445,6 @@ def initialize_population(self,
14821445
14831446 if self .gene_space [gene_idx ] is None :
14841447
1485- # The following commented code replace the None value with a single number that will not change again.
1486- # This means the gene value will be the same across all solutions.
1487- # self.gene_space[gene_idx] = numpy.asarray(numpy.random.uniform(low=low,
1488- # high=high,
1489- # size=1), dtype=self.gene_type[0])[0]
1490- # self.population[sol_idx, gene_idx] = list(self.gene_space[gene_idx]).copy()
1491-
14921448 # The above problem is solved by keeping the None value in the gene_space parameter. This forces PyGAD to generate this value for each solution.
14931449 self .population [sol_idx , gene_idx ] = numpy .asarray (numpy .random .uniform (low = range_min ,
14941450 high = range_max ,
@@ -1503,8 +1459,7 @@ def initialize_population(self,
15031459 # We copy the gene_space to a temp variable to keep its original value.
15041460 # In the next for loop, the gene_space is changed.
15051461 # Later, the gene_space is restored to its original value using the temp variable.
1506- temp_gene_space = list (
1507- self .gene_space [gene_idx ]).copy ()
1462+ temp_gene_space = list (self .gene_space [gene_idx ]).copy ()
15081463
15091464 for idx , val in enumerate (self .gene_space [gene_idx ]):
15101465 if val is None :
@@ -1586,7 +1541,7 @@ def initialize_population(self,
15861541 high = self .gene_space [gene_idx ]['high' ],
15871542 size = 1 ),
15881543 dtype = self .gene_type [gene_idx ][0 ])[0 ]
1589- elif type ( self .gene_space [gene_idx ]) == type ( None ) :
1544+ elif self .gene_space [gene_idx ] is None :
15901545 temp_gene_value = numpy .asarray (numpy .random .uniform (low = range_min ,
15911546 high = range_max ,
15921547 size = 1 ),
@@ -1676,7 +1631,9 @@ def initialize_population(self,
16761631 # Adding the current gene values to the population.
16771632 self .population [:, gene_idx ] = gene_values
16781633
1679- if not (self .gene_space is None ):
1634+ if self .gene_space is None :
1635+ pass
1636+ else :
16801637 if allow_duplicate_genes == False :
16811638 for sol_idx in range (self .population .shape [0 ]):
16821639 self .population [sol_idx ], _ , _ = self .solve_duplicate_genes_by_space (solution = self .population [sol_idx ],
0 commit comments