import numpy as np import random def de_cp( fobj, # objective function, serial eval bounds, # bounds array for the population pop=[], # already initialized population history=[], # previous history that will be appended to it_start=0, # the start index of the iteration mut=0.8, # mutation rate crossp=0.7, # crossover popsize=20, # the population size its=1000, # the number of iterations needed to run for **kwargs ): """ This function performs diff evolution using fobj evaluated in parallel returns the last pop, fitness of pop, best individual and opt history """ #mut = 0.8 + 0.6*np.random.random() dimensions = len(bounds) history=[] min_b, max_b = np.asarray(bounds).T if pop == []: pop = np.random.rand(popsize, dimensions) diff = np.fabs(min_b - max_b) pop_denorm = min_b + pop * diff fitness = np.asarray(fobj(pop_denorm, **kwargs)) best_idx = np.argmin(fitness) best = pop_denorm[best_idx] for i in range(its): trialarr = np.zeros((popsize, dimensions)) for j in range(popsize): idxs = [idx for idx in range(popsize) if idx != j] a, b, c = pop[np.random.choice(idxs, 3, replace = False)] #mutant = np.clip(a + mut * (b - c), 0, 1) mutant = np.clip(pop[best_idx] + mut * (b - c), 0, 1) cross_points = np.random.rand(dimensions) < crossp if not np.any(cross_points): cross_points[np.random.randint(0, dimensions)] = True trialarr[j] = np.where(cross_points, mutant, pop[j]) trial_denorm = min_b + trialarr * diff f = fobj(trial_denorm, **kwargs) for j in range(popsize): if f[j] < fitness[j]: fitness[j] = f[j] pop[j] = trialarr[j] if f[j] < fitness[best_idx]: best_idx = j best = trial_denorm[j] if (i+1)%20 == 0: print(i, fitness[best_idx]) history.append([i, fitness[best_idx]]) return pop, best_idx, fitness[best_idx], best def de_c( fobj, # objective function, serial eval bounds, # bounds array for the population pop=[], # already initialized population history=[], # previous history that will be appended to it_start=0, # the start index of the iteration mut=0.8, # mutation rate crossp=0.8, # crossover popsize=20, # the population size its=1000, # the number of iterations needed to run for **kwargs ): """ This function performs diff evolution using fobj evaluated serially. returns the best, fitness of the best, and opt history """ dimensions = len(bounds) min_b, max_b = np.asarray(bounds).T diff = np.fabs(min_b - max_b) if pop == []: pop = np.random.rand(popsize, dimensions) pop_denorm = min_b + pop * diff fitness = np.asarray([fobj(ind, **kwargs) for ind in pop_denorm]) best_idx = np.argmin(fitness) best = pop_denorm[best_idx] for i in range(its): for j in range(popsize): idxs = [idx for idx in range(popsize) if idx != j] a, b, c = pop[np.random.choice(idxs, 3, replace=False)] mutant = np.clip(a + mut * (b - c), 0, 1) # #TODO: Here we can chage the strategy for instance # if i >=150: # if random.random() >=0.82: # mutant = np.clip(a + mut * (b - c), 0, 1) # else: # mutant = np.clip(pop[best_idx] + mut * (b - c), 0, 1) cross_points = np.random.rand(dimensions) < crossp if not np.any(cross_points): cross_points[np.random.randint(0, dimensions)] = True trial = np.where(cross_points, mutant, pop[j]) trial_denorm = min_b + trial * diff f = fobj(trial_denorm, **kwargs) if f < fitness[j]: fitness[j] = f pop[j] = trial if f < fitness[best_idx]: best_idx = j best = trial_denorm if i % 5 == 0: print(i, fitness[best_idx]) history.append([i + it_start, fitness[best_idx]]) return best, fitness[best_idx], history def de_g( fobj, # objsctive function, parallel eval bounds, # bounds array for the population mut=0.8, # mutation rate crossp=0.7, # crossover popsize=20, # the population size its=1000, # the number of iterations needed to run for **kwargs ): """ This function performs diff evolution using fobj evaluated in parallel returns the last pop, fitness of pop, best individual and opt history """ dimensions = len(bounds) history=[] pop = np.random.rand(popsize, dimensions) min_b, max_b = np.asarray(bounds).T diff = np.fabs(min_b - max_b) pop_denorm = min_b + pop * diff fitness = np.asarray(fobj(pop_denorm, **kwargs)) best_idx = np.argmin(fitness) best = pop_denorm[best_idx] for i in range(its): trialarr = np.zeros((popsize, dimensions)) for j in range(popsize): idxs = [idx for idx in range(popsize) if idx != j] a, b, c = pop[np.random.choice(idxs, 3, replace = False)] #mutant = np.clip(a + mut * (b - c), 0, 1) mutant = np.clip(pop[best_idx] + mut * (b - c), 0, 1) cross_points = np.random.rand(dimensions) < crossp if not np.any(cross_points): cross_points[np.random.randint(0, dimensions)] = True trialarr[j] = np.where(cross_points, mutant, pop[j]) trial_denorm = min_b + trialarr * diff f = fobj(trial_denorm, **kwargs) for j in range(popsize): if f[j] < fitness[j]: fitness[j] = f[j] pop[j] = trialarr[j] if f[j] < fitness[best_idx]: best_idx = j best = trial_denorm[j] # if i%50 == 0: # print(i, fitness[best_idx]) history.append([i, fitness[best_idx]]) return pop, fitness, best, history