@@ -432,9 +432,7 @@ def __init__(self,
432
432
433
433
# Number of solutions in the population.
434
434
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 ,
438
436
mutation_by_replacement = True ,
439
437
gene_type = self .gene_type ,
440
438
gene_constraint = gene_constraint )
@@ -457,32 +455,7 @@ def __init__(self,
457
455
self .valid_parameters = False
458
456
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." )
459
457
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.
486
459
if self .allow_duplicate_genes == False :
487
460
for initial_solution_idx , initial_solution in enumerate (self .initial_population ):
488
461
if self .gene_space is None :
@@ -497,6 +470,9 @@ def __init__(self,
497
470
gene_type = self .gene_type ,
498
471
num_trials = 10 )
499
472
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
+
500
476
# A NumPy array holding the initial population.
501
477
self .population = self .initial_population .copy ()
502
478
# Number of genes in the solution.
@@ -506,9 +482,9 @@ def __init__(self,
506
482
# The population size.
507
483
self .pop_size = (self .sol_per_pop , self .num_genes )
508
484
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 ( )
512
488
513
489
# In case the 'gene_space' parameter is nested, then make sure the number of its elements equals to the number of genes.
514
490
if self .gene_space_nested :
@@ -1375,8 +1351,6 @@ def round_genes(self, solutions):
1375
1351
return solutions
1376
1352
1377
1353
def initialize_population (self ,
1378
- low ,
1379
- high ,
1380
1354
allow_duplicate_genes ,
1381
1355
mutation_by_replacement ,
1382
1356
gene_type ,
@@ -1385,8 +1359,6 @@ def initialize_population(self,
1385
1359
Creates an initial population randomly as a NumPy array. The array is saved in the instance attribute named 'population'.
1386
1360
1387
1361
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.
1390
1362
-allow_duplicate_genes: Whether duplicate genes are allowed or not.
1391
1363
-mutation_by_replacement: Whether mutation by replacement is enabled or not.
1392
1364
-gene_type: The data type of the genes.
@@ -1403,39 +1375,31 @@ def initialize_population(self,
1403
1375
self .pop_size = (self .sol_per_pop , self .num_genes )
1404
1376
1405
1377
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.
1419
1379
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 )
1421
1386
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
1429
1393
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 )
1432
1396
1433
1397
# Enforce the gene constraints as much as possible.
1434
1398
if gene_constraint is None :
1435
1399
pass
1436
1400
else :
1437
1401
# 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.
1439
1403
self .gene_constraint = gene_constraint
1440
1404
for sol_idx , solution in enumerate (self .population ):
1441
1405
for gene_idx in range (self .num_genes ):
@@ -1461,12 +1425,11 @@ def initialize_population(self,
1461
1425
for solution_idx in range (self .population .shape [0 ]):
1462
1426
# self.logger.info("Before", self.population[solution_idx])
1463
1427
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 ,
1466
1430
mutation_by_replacement = True ,
1467
1431
gene_type = gene_type ,
1468
1432
sample_size = 100 )
1469
- # self.logger.info("After", self.population[solution_idx])
1470
1433
1471
1434
elif self .gene_space_nested :
1472
1435
if self .gene_type_single == True :
@@ -1482,13 +1445,6 @@ def initialize_population(self,
1482
1445
1483
1446
if self .gene_space [gene_idx ] is None :
1484
1447
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
-
1492
1448
# 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.
1493
1449
self .population [sol_idx , gene_idx ] = numpy .asarray (numpy .random .uniform (low = range_min ,
1494
1450
high = range_max ,
@@ -1503,8 +1459,7 @@ def initialize_population(self,
1503
1459
# We copy the gene_space to a temp variable to keep its original value.
1504
1460
# In the next for loop, the gene_space is changed.
1505
1461
# 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 ()
1508
1463
1509
1464
for idx , val in enumerate (self .gene_space [gene_idx ]):
1510
1465
if val is None :
@@ -1586,7 +1541,7 @@ def initialize_population(self,
1586
1541
high = self .gene_space [gene_idx ]['high' ],
1587
1542
size = 1 ),
1588
1543
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 :
1590
1545
temp_gene_value = numpy .asarray (numpy .random .uniform (low = range_min ,
1591
1546
high = range_max ,
1592
1547
size = 1 ),
@@ -1676,7 +1631,9 @@ def initialize_population(self,
1676
1631
# Adding the current gene values to the population.
1677
1632
self .population [:, gene_idx ] = gene_values
1678
1633
1679
- if not (self .gene_space is None ):
1634
+ if self .gene_space is None :
1635
+ pass
1636
+ else :
1680
1637
if allow_duplicate_genes == False :
1681
1638
for sol_idx in range (self .population .shape [0 ]):
1682
1639
self .population [sol_idx ], _ , _ = self .solve_duplicate_genes_by_space (solution = self .population [sol_idx ],
0 commit comments