一、什么是进化策略
进化策略和遗传算法都使用到了遗传信息,比较DNA,然后繁衍变异,从而获取上一代没有的东西。然后通过适者生存不适者淘汰的这一套理论不断进化。
那下面来看下进化策略与遗传算法的不同。
就遗传算法来说,遗传算法使用的DNA是二进制编码的,爸妈的DNA交叉配对组成宝宝的DNA,宝宝也会再进行一定的变异获得新的属性,但是一般的进化策略却略有不同。
二、代码实现进化策略
整个程序基本就是生孩子丢掉坏孩子的过程,每次就是生孩子然后将父母和孩子放在一起去计算他们的fitness,然后排序取前面一段作为新的population
import numpy as npimport matplotlib.pyplot as pltDNA_SIZE = 1 # DNA (real number)DNA_BOUND = [0, 5] # solution upper and lower boundsN_GENERATIONS = 200POP_SIZE = 100 # population sizeN_KID = 50 # n kids per generationdef F(x): return np.sin(10*x)*x + np.cos(2*x)*x # to find the maximum of this function# find non-zero fitness for selectiondef get_fitness(pred): return pred.flatten()#生宝宝def make_kid(pop, n_kid): # generate empty kid holder kids = {'DNA': np.empty((n_kid, DNA_SIZE))} kids['mut_strength'] = np.empty_like(kids['DNA']) for kv, ks in zip(kids['DNA'], kids['mut_strength']): # crossover (roughly half p1 and half p2) 选择父亲和母亲 p1, p2 = np.random.choice(np.arange(POP_SIZE), size=2, replace=False) cp = np.random.randint(0, 2, DNA_SIZE, dtype=np.bool) # crossover points 选两个点 kv[cp] = pop['DNA'][p1, cp] kv[~cp] = pop['DNA'][p2, ~cp] ks[cp] = pop['mut_strength'][p1, cp] ks[~cp] = pop['mut_strength'][p2, ~cp] # mutate (change DNA based on normal distribution) #让变异强度也进行变异,因为随着结果的慢慢收敛,我们也希望变异强度越来越小,这样才能更好更快的收敛 ks[:] = np.maximum(ks + (np.random.rand(*ks.shape)-0.5), 0.) # must > 0 kv += ks * np.random.randn(*kv.shape) kv[:] = np.clip(kv, *DNA_BOUND) # clip the mutated value return kids 将数据都控制在DNA范围内#丢掉坏宝宝def kill_bad(pop, kids): # put pop and kids together for key in ['DNA', 'mut_strength']: pop[key] = np.vstack((pop[key], kids[key])) fitness = get_fitness(F(pop['DNA'])) # calculate global fitness idx = np.arange(pop['DNA'].shape[0]) good_idx = idx[fitness.argsort()][-POP_SIZE:] # selected by fitness ranking (not value) for key in ['DNA', 'mut_strength']: pop[key] = pop[key][good_idx] return pop#生成population,在这里我们不仅要生成DNA还要生成mutation strength变异强度pop = dict(DNA=5 * np.random.rand(1, DNA_SIZE).repeat(POP_SIZE, axis=0), # initialize the pop DNA values mut_strength=np.random.rand(POP_SIZE, DNA_SIZE)) # initialize the pop mutation strength valuesplt.ion() # something about plottingx = np.linspace(*DNA_BOUND, 200)plt.plot(x, F(x))for _ in range(N_GENERATIONS): # something about plotting if 'sca' in globals(): sca.remove() sca = plt.scatter(pop['DNA'], F(pop['DNA']), s=200, lw=0, c='red', alpha=0.5); plt.pause(0.05) # ES part 整个进化的循环其实就是不断的生小孩和丢掉坏小孩的过程 kids = make_kid(pop, N_KID) pop = kill_bad(pop, kids) # keep some good parent for elitismplt.ioff(); plt.show()
联系客服