def test_basic_functions(algo_version, func, bounds, expected): algo = algo_version(seed=SEED) algo_control = AlgorithmControl(func, 1000, 1, expected) # https://stackoverflow.com/questions/2138873/cleanest-way-to-get-last-item-from-python-iterator result = algo.run(algo_control, bounds, init_population_uniform) assert np.allclose(result, np.array(expected), atol=EPSILON)
def run_single_problem(problem, de: DifferentialEvolution, max_fes=None): dims, func_num = problem if max_fes is None: max_fes = MAX_FES_FACTOR * dims bounds = BOUNDS_1D * dims target_value = TARGET_VALUE_FACTOR * func_num def call_cec(x): fitness = cec17_test_func(x, dims=dims, func_num=func_num) return fitness[0] algo_control = AlgorithmControl(call_cec, max_fes, dims, target_value) de.run(algo_control, bounds, init_population_uniform) algo_control.fill_up_recorder_values() return algo_control.recorded_values, algo_control.error()
def test_alpine(algo_version): algo = algo_version(seed=SEED) bounds = [(-5, 5)] * 2 def alpine_one(X): return sum([abs(x * np.sin(x) + 0.1 * x) for x in X]) algo_control = AlgorithmControl(alpine_one, 1000, 1, 0) result = algo.run(algo_control, bounds, init_population_uniform, population_size=20) assert np.allclose(result, np.array([0, 0]), atol=0.2)
def run( self, algorithm_control: AlgorithmControl, bounds: List[Tuple[float, float]], population_initializer: Callable, population_size=None, ): dimensions = len(bounds) if not population_size: population_size = 4 * dimensions pop = population_initializer(population_size, bounds) fitness = np.asarray([algorithm_control.test_func(ind) for ind in pop]) best_idx = np.argmin(fitness) algorithm_control.update_best_fitness(fitness[best_idx]) best = pop[best_idx] self.population_history = [pop.copy()] mn, mx = np.array(bounds).T while algorithm_control.check_stop_criteria(): for j in range(population_size): idxs = [idx for idx in range(population_size) if idx != j] for retry in range(population_size): a, b, c = pop[np.random.choice(idxs, 3, replace=False)] mutation_factorant = a + self.mutation_factor * (b - c) if within_bounds(mutation_factorant, mn, mx): break elif retry == population_size - 1: mutation_factorant = np.clip( mutation_factorant, mn, mx, ) cross_points = np.random.rand(dimensions) < self.crossover trial = np.where(cross_points, mutation_factorant, pop[j]) f = algorithm_control.test_func(trial) if f is None: break if f < fitness[j]: fitness[j] = f pop[j] = trial if f < fitness[best_idx]: best_idx = j best = trial algorithm_control.update_best_fitness(f) self.population_history += [pop.copy()] return best
def test_cec(algo_version): dims = 2 bounds = [(-100, 100)] * dims def call_cec(x): fitness = cec17_test_func(x, dims=len(bounds), func_num=1) return fitness[0] algo = algo_version(seed=SEED) algo_control = AlgorithmControl(call_cec, 100000, 1, 100) result = algo.run(algo_control, bounds, init_population_uniform, population_size=20) # values taken from shift_data_1.txt assert np.allclose( result, np.array([-5.5276398498228005e01, -7.0429559718086182e01]), atol=EPSILON, )
max_fes = MAX_FES_FACTOR * dims bounds = BOUNDS_1D * dims linestyles = ["-", "--", "-."] fig, ax = plt.subplots(2) for algo_version, linestyle in zip([ConstantDE, ConstantSuccessRuleDE], linestyles): for retry in range(5): algo = algo_version() def call_cec(x): return np.sum(x**2) target_value = 0 algo_control = AlgorithmControl(call_cec, max_fes, dims, target_value) best_point = algo.run(algo_control, bounds, init_population_uniform) x = list(range(len(algo.population_history))) y = [] for population in algo.population_history: y += [min([call_cec(member) for member in population])] error = f"{abs(call_cec(best_point) - target_value):.2E}" ax[0].plot( x, y, label=f"{algo_version.__name__}-{retry} ({error})", linestyle=linestyle, ) ax[0].hlines(