@@ -112,12 +112,14 @@ def tournament_selection(self, fitness, num_parents):
112112 parents = self .initialize_parents_array ((num_parents , self .population .shape [1 ]))
113113 parents_indices = []
114114
115+ rank_lookup = {sol_idx : rank for rank , sol_idx in enumerate (fitness_sorted )}
116+
115117 for parent_num in range (num_parents ):
116118 # Generate random indices for the candidate solutions.
117119 rand_indices = numpy .random .randint (low = 0 , high = len (fitness ), size = self .K_tournament )
118120
119121 # Find the rank of the candidate solutions. The lower the rank, the better the solution.
120- rand_indices_rank = [fitness_sorted . index ( rand_idx ) for rand_idx in rand_indices ]
122+ rand_indices_rank = [rank_lookup [ rand_idx ] for rand_idx in rand_indices ]
121123 # Select the solution with the lowest rank as a parent.
122124 selected_parent_idx = rand_indices_rank .index (min (rand_indices_rank ))
123125
@@ -196,17 +198,10 @@ def wheel_cumulative_probs(self, probs, num_parents):
196198 probs_start = numpy .zeros (probs .shape , dtype = float ) # An array holding the start values of the ranges of probabilities.
197199 probs_end = numpy .zeros (probs .shape , dtype = float ) # An array holding the end values of the ranges of probabilities.
198200
199- curr = 0.0
200-
201- # Calculating the probabilities of the solutions to form a roulette wheel.
202- for _ in range (probs .shape [0 ]):
203- min_probs_idx = numpy .where (probs == numpy .min (probs ))[0 ][0 ]
204- probs_start [min_probs_idx ] = curr
205- curr = curr + probs [min_probs_idx ]
206- probs_end [min_probs_idx ] = curr
207- # Replace 99999999999 by float('inf')
208- # probs[min_probs_idx] = 99999999999
209- probs [min_probs_idx ] = float ('inf' )
201+ sorted_indices = numpy .argsort (probs )
202+ cumulative = numpy .cumsum (probs [sorted_indices ])
203+ probs_start [sorted_indices ] = numpy .concatenate ([[0.0 ], cumulative [:- 1 ]])
204+ probs_end [sorted_indices ] = cumulative
210205
211206 # Selecting the best individuals in the current generation as parents for producing the offspring of the next generation.
212207 parents = self .initialize_parents_array ((num_parents , self .population .shape [1 ]))
@@ -248,18 +243,8 @@ def stochastic_universal_selection(self, fitness, num_parents):
248243
249244 probs = fitness / fitness_sum
250245
251- probs_start = numpy .zeros (probs .shape , dtype = float ) # An array holding the start values of the ranges of probabilities.
252- probs_end = numpy .zeros (probs .shape , dtype = float ) # An array holding the end values of the ranges of probabilities.
253-
254- curr = 0.0
255-
256- # Calculating the probabilities of the solutions to form a roulette wheel.
257- for _ in range (probs .shape [0 ]):
258- min_probs_idx = numpy .where (probs == numpy .min (probs ))[0 ][0 ]
259- probs_start [min_probs_idx ] = curr
260- curr = curr + probs [min_probs_idx ]
261- probs_end [min_probs_idx ] = curr
262- probs [min_probs_idx ] = float ('inf' )
246+ probs_start , probs_end , parents = self .wheel_cumulative_probs (probs = probs .copy (),
247+ num_parents = num_parents )
263248
264249 pointers_distance = 1.0 / self .num_parents_mating # Distance between different pointers.
265250 first_pointer = numpy .random .uniform (low = 0.0 ,
0 commit comments