From 49b28a9bde38e452031c69e0d67d0b18f89910f4 Mon Sep 17 00:00:00 2001 From: waterfall-xi <146172962+waterfall-xi@users.noreply.github.com> Date: Sat, 14 Oct 2023 22:42:36 +0800 Subject: [PATCH] Update GA.py to add class EGA to achieve GA with elitist machine define class EGA from GA; `self._n_elitist = n_elitist` in `__init__()`; redefine run() in EGA, in each iteration, isolate top n fitted elitists out from population, add them back after selection(), crossover() and mutation(). --- sko/GA.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/sko/GA.py b/sko/GA.py index 8a90f24..3c9925c 100644 --- a/sko/GA.py +++ b/sko/GA.py @@ -256,6 +256,68 @@ def chrom2x(self, Chrom): return self +class EGA(GA): + """ + + """ + def __init__(self, func, n_dim, + size_pop=50, max_iter=200, + prob_mut=0.001, n_elitist=0, + lb=-1, ub=1, + constraint_eq=tuple(), constraint_ueq=tuple(), + precision=1e-7, early_stop=None): + super().__init__(func, n_dim, size_pop, max_iter, prob_mut, lb, ub, constraint_eq, constraint_ueq, precision, + early_stop) + self._n_elitist = n_elitist + + def run(self, max_iter=None): + self.max_iter = max_iter or self.max_iter + best = [] + for i in range(self.max_iter): + self.X = self.chrom2x(self.Chrom) + self.Y = self.x2y() + self.ranking() + + # select elitists do not selection(), crossover() and mutation() and remove them from population + # provisionally. + idx_elitist = np.sort(self.Y.argsort()[0:self._n_elitist]) + self.size_pop -= self._n_elitist + elitist_FitV = np.take(self.FitV, idx_elitist, axis=0) + self.FitV = np.delete(self.FitV, idx_elitist, axis=0) + elitist_Chrom = np.take(self.Chrom, idx_elitist, axis=0) + self.Chrom = np.delete(self.Chrom, idx_elitist, axis=0) + + self.selection() + self.crossover() + self.mutation() + + # add elitists back to next generation population. + idx_insert = np.array([idx_v - i for i, idx_v in enumerate(idx_elitist)]) + self.size_pop += self._n_elitist + self.FitV = np.insert(self.FitV, idx_insert, elitist_FitV, axis=0) + self.Chrom = np.insert(self.Chrom, idx_insert, elitist_Chrom, axis=0) + + # record the best ones + generation_best_index = self.FitV.argmax() + self.generation_best_X.append(self.X[generation_best_index, :]) + self.generation_best_Y.append(self.Y[generation_best_index]) + self.all_history_Y.append(self.Y) + self.all_history_FitV.append(self.FitV) + + if self.early_stop: + best.append(min(self.generation_best_Y)) + if len(best) >= self.early_stop: + if best.count(min(best)) == len(best): + break + else: + best.pop(0) + + global_best_index = np.array(self.generation_best_Y).argmin() + self.best_x = self.generation_best_X[global_best_index] + self.best_y = self.func(np.array([self.best_x])) + return self.best_x, self.best_y + + class RCGA(GeneticAlgorithmBase): """real-coding genetic algorithm