@@ -2227,8 +2227,27 @@ def best_solution(self, pop_fitness=None):
2227
2227
raise ValueError (f"The type of the 'pop_fitness' parameter is expected to be list, tuple, or numpy.ndarray but ({ type (pop_fitness )} ) found." )
2228
2228
2229
2229
# Return the index of the best solution that has the best fitness value.
2230
- best_match_idx = numpy .where (
2231
- pop_fitness == numpy .max (pop_fitness ))[0 ][0 ]
2230
+ # For multi-objective optimization: find the index of the solution with the maximum fitness in the first objective,
2231
+ # break ties using the second objective, then third, etc.
2232
+ pop_fitness_arr = numpy .array (pop_fitness )
2233
+ # Get the indices that would sort by all objectives in descending order
2234
+ if pop_fitness_arr .ndim == 1 :
2235
+ # Single-objective optimization.
2236
+ best_match_idx = numpy .where (
2237
+ pop_fitness == numpy .max (pop_fitness ))[0 ][0 ]
2238
+ elif pop_fitness_arr .ndim == 2 :
2239
+ # Multi-objective optimization.
2240
+ # Sort by all objectives in descending order.
2241
+ # The first objective is the most important, then the second, etc.
2242
+ sorted_indices = numpy .lexsort ([ - pop_fitness_arr [:,i ] for i in reversed (range (pop_fitness_arr .shape [1 ])) ])
2243
+ best_match_idx = sorted_indices [0 ]
2244
+ maximum_fitness_value = pop_fitness_arr [best_match_idx ]
2245
+
2246
+ best_match_list = numpy .where (
2247
+ pop_fitness == maximum_fitness_value )
2248
+
2249
+ best_match_idx = best_match_list [0 ][0 ] # Get the first index of the best match.
2250
+
2232
2251
2233
2252
best_solution = self .population [best_match_idx , :].copy ()
2234
2253
best_solution_fitness = pop_fitness [best_match_idx ]
@@ -2494,4 +2513,4 @@ def load(filename):
2494
2513
except :
2495
2514
# raise BaseException("Error loading the file. If the file already exists, please reload all the functions previously used (e.g. fitness function).")
2496
2515
raise BaseException ("Error loading the file." )
2497
- return ga_in
2516
+ return ga_in
0 commit comments