|
1 | 1 | import numpy
|
| 2 | +import pygad |
2 | 3 |
|
3 | 4 | def get_non_dominated_set(curr_solutions):
|
4 | 5 | """
|
@@ -208,3 +209,43 @@ def crowding_distance(pareto_front, fitness):
|
208 | 209 | crowding_dist_pop_sorted_indices = crowding_dist_pop_sorted_indices.astype(int)
|
209 | 210 |
|
210 | 211 | return obj_crowding_dist_list, crowding_dist_sum, crowding_dist_front_sorted_indices, crowding_dist_pop_sorted_indices
|
| 212 | + |
| 213 | +def sort_solutions_nsga2(fitness): |
| 214 | + """ |
| 215 | + Sort the solutions based on the fitness. |
| 216 | + The sorting procedure differs based on whether the problem is single-objective or multi-objective optimization. |
| 217 | + If it is multi-objective, then non-dominated sorting and crowding distance are applied. |
| 218 | + At first, non-dominated sorting is applied to classify the solutions into pareto fronts. |
| 219 | + Then the solutions inside each front are sorted using crowded distance. |
| 220 | + The solutions inside pareto front X always come before those in front X+1. |
| 221 | +
|
| 222 | + Parameters |
| 223 | + ---------- |
| 224 | + fitness : TYPE |
| 225 | + The fitness of the entire population. |
| 226 | +
|
| 227 | + Returns |
| 228 | + ------- |
| 229 | + solutions_sorted : TYPE |
| 230 | + The indices of the sorted solutions. |
| 231 | +
|
| 232 | + """ |
| 233 | + if type(fitness[0]) in [list, tuple, numpy.ndarray]: |
| 234 | + # Multi-objective optimization problem. |
| 235 | + solutions_sorted = [] |
| 236 | + # Split the solutions into pareto fronts using non-dominated sorting. |
| 237 | + pareto_fronts, solutions_fronts_indices = non_dominated_sorting(fitness) |
| 238 | + for pareto_front in pareto_fronts: |
| 239 | + # Sort the solutions in the front using crowded distance. |
| 240 | + _, _, _, crowding_dist_pop_sorted_indices = crowding_distance(pareto_front=pareto_front.copy(), |
| 241 | + fitness=fitness) |
| 242 | + crowding_dist_pop_sorted_indices = list(crowding_dist_pop_sorted_indices) |
| 243 | + # Append the sorted solutions into the list. |
| 244 | + solutions_sorted.extend(crowding_dist_pop_sorted_indices) |
| 245 | + elif type(fitness[0]) in pygad.GA.supported_int_float_types: |
| 246 | + # Single-objective optimization problem. |
| 247 | + solutions_sorted = sorted(range(len(fitness)), key=lambda k: fitness[k]) |
| 248 | + # Reverse the sorted solutions so that the best solution comes first. |
| 249 | + solutions_sorted.reverse() |
| 250 | + |
| 251 | + return solutions_sorted |
0 commit comments