@@ -2227,8 +2227,27 @@ def best_solution(self, pop_fitness=None):
22272227 raise ValueError (f"The type of the 'pop_fitness' parameter is expected to be list, tuple, or numpy.ndarray but ({ type (pop_fitness )} ) found." )
22282228
22292229 # 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+
22322251
22332252 best_solution = self .population [best_match_idx , :].copy ()
22342253 best_solution_fitness = pop_fitness [best_match_idx ]
@@ -2494,4 +2513,4 @@ def load(filename):
24942513 except :
24952514 # raise BaseException("Error loading the file. If the file already exists, please reload all the functions previously used (e.g. fitness function).")
24962515 raise BaseException ("Error loading the file." )
2497- return ga_in
2516+ return ga_in
0 commit comments