123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- 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
|