差分进化是一种基于种群的算法。然而,scipy.optimize.differential_evolution
将结果返回为OptimizeResult
,这只给出了种群中最好的精英,而忽略了其其余世代。
一个人如何保存关于最后一批人的信息?
我发现返回最后一个填充的一种方法是下载源代码并直接使用类DifferentialEvolutionSolver
:
solver = DifferentialEvolutionSolver(fun, bounds, arg**)
solver.init_population_random()
solver.__next__() # for each generation
last_pop = solver.population
las_pop_costs = solver.population_energies
可以在每次迭代中使用workers
关键字来接受像callable
这样的映射,该映射发送给整个试验群体,并期望返回一个数组,其中包含为整个试验群体评估的函数值:
from scipy.optimize import rosen, differential_evolution
bounds=[(0, 10), (0, 10)]
# pop will retain the trial population at each iteration of the minimisation
pop = []
energies = []
def maplike_fun(func, x):
# x.shape == (S, N), where S is the size of the population and N
# is the number of parameters. The rosen function is vectorised,
# so calling rosen with x.T will return an array of shape (S,)
# you could also do:
# v = np.array(list(map(func, x)))
pop.append(np.copy(x))
e = func(x.T)
energies.append(e)
return e
res = differential_evolution(rosen, bounds, workers=maplike_fun, polish=False, updating='deferred')
# the initial evaluation of the population is not counted in the number
# of iterations, so pop[0] is the initial population.
assert res.nit == len(pop) - 1
要在每次迭代中获得实际群体,您需要迭代试验群体列表,并依次更新pop[0]
:
pop_up = [pop[0]]
energies_up = [energies[0]]
for i in range(1, len(pop)):
new_energies = np.copy(energies_up[-1])
new_pop = np.copy(pop_up[-1])
pos = energies[i] < new_energies
new_energies[pos] = energies[i][pos]
new_pop[pos] = pop[i][pos]
pop_up.append(new_pop)
energies_up.append(new_energies)
然后用pop_up
描述实际的种群进化。
从scipy 1.9开始,还会有一个vectorized
关键字,它会在每次迭代时将整个试验群体发送到目标函数。