遗传算法作为一种基础的优化算法广泛应用于各种优化计算中。在这里列出一个简单的遗传算法程序,计算Σx^2的极小值点。
1、基本参数设置
x_range = 10genuine = 100genuine_cross = 0.1genuine_change = 0.01epoch = 500x_max = 20x_min = -20
计算x12+x22+……+x102的计算结果,x共计十组,样本100个,交叉概率10%,变异概率1%,x范围为[-20,20],计算500步。
2、适应度函数
sum(x ** 2)
返回所有输入的平方和
3、创建初始数据
son_population = numpy.zeros(shape=(x_range, genuine))population = numpy.random.rand(x_range, genuine)\* (x_max - x_min) + x_minfather_genuine_value = []for i in range(genuine):father_genuine_value.append(function(population[:, i]))passfather_genuine_value = numpy.reshape(father_genuine_value, newshape=(len(father_genuine_value)))first_genuine_sort = numpy.sort(father_genuine_value, axis=0)first_genuine_index = numpy.argsort(father_genuine_value, axis=0)father_value = population[:, first_genuine_index]
4、交叉
emper = father_value[:, 1]crosspoint_number = numpy.round(genuine * genuine_cross)crosspoint = numpy.random.randint(1, x_range, size=(int(crosspoint_number)\, int(genuine / 2)))son_population[:, :] = numpy.reshape(father_value, newshape=(10, -1))for i in range(int(genuine / 2)):son_population[:, 2 * i - 1] = emperson_population[:, 2 * i] = father_value[:, 2 * i]for j in range(int(crosspoint_number)):son_population[int(crosspoint[j, i]), 2 * i - 1] = son_population[int(crosspoint[j, i]), 2 * i]son_population[int(crosspoint[j, i]), 2 * i] = emper[int(crosspoint[j, i])]
5、变异
for i in range(genuine):for j in range(x_range):expire = numpy.random.rand()if expire < genuine_cross:son_population[j, i] = numpy.random.rand() * \(x_max - x_min) + x_min
6、子代分析
son_genuine_value = []for i in range(genuine):son_genuine_value.append(function(son_population[:, i]))passson_genuine_value = numpy.reshape(son_genuine_value, \newshape=(len(son_genuine_value)))son_genuine_sort = numpy.sort(son_genuine_value, axis=0)son_genuine_index = numpy.argsort(son_genuine_value, axis=0)son_value = son_population[:, son_genuine_index]
7、产生新子代
all_population = numpy.concatenate((father_value, son_value), axis=1)genuine_value = numpy.concatenate((first_genuine_sort, \son_genuine_sort), axis=0)genuine_sort = numpy.sort(genuine_value)genuine_index = numpy.argsort(genuine_value)father_son_value = all_population[:, genuine_index]first_genuine_sort = genuine_sort[0:genuine]father_value = father_son_value[:, 0:genuine]value.append(first_genuine_sort[0])
8、完整代码
import matplotlib.pyplot as pltimport numpyclass genuine():def __init__(self):self.x_range = 10self.genuine = 100self.genuine_cross = 0.1self.genuine_change = 0.01self.epoch = 500self.x_max = 20self.x_min = -20self.father_genuine_value = []self.son_genuine_value = []self.value = []def function(self,x):return sum(x ** 2)def origin_data(self):son_population = numpy.zeros(shape=(self.x_range, self.genuine))population = numpy.random.rand(self.x_range, self.genuine)\* (self.x_max - self.x_min) + self.x_minfather_genuine_value = []for i in range(self.genuine):father_genuine_value.append(self.function(population[:, i]))passfather_genuine_value = numpy.reshape(father_genuine_value, newshape=(len(father_genuine_value)))first_genuine_sort = numpy.sort(father_genuine_value, axis=0)first_genuine_index = numpy.argsort(father_genuine_value, axis=0)father_value = population[:, first_genuine_index]return population,son_population,father_value,first_genuine_sortdef cross_function(self,son_population,father_value):emper = father_value[:, 1]crosspoint_number = numpy.round(self.genuine * self.genuine_cross)crosspoint = numpy.random.randint(1, self.x_range, size=(int(crosspoint_number)\, int(self.genuine / 2)))son_population[:, :] = numpy.reshape(father_value, newshape=(10, -1))for i in range(int(self.genuine / 2)):son_population[:, 2 * i - 1] = emperson_population[:, 2 * i] = father_value[:, 2 * i]for j in range(int(crosspoint_number)):son_population[int(crosspoint[j, i]), 2 * i - 1] = son_population[int(crosspoint[j, i]), 2 * i]son_population[int(crosspoint[j, i]), 2 * i] = emper[int(crosspoint[j, i])]passpassreturn son_populationdef variation_function(self,son_population):for i in range(self.genuine):for j in range(self.x_range):expire = numpy.random.rand()if expire < self.genuine_cross:son_population[j, i] = numpy.random.rand() * \(self.x_max - self.x_min) + self.x_minpasspasspassreturn son_populationdef son_genuine_analyze(self,son_population):son_genuine_value = []for i in range(self.genuine):son_genuine_value.append(self.function(son_population[:, i]))passson_genuine_value = numpy.reshape(son_genuine_value, \newshape=(len(son_genuine_value)))son_genuine_sort = numpy.sort(son_genuine_value, axis=0)son_genuine_index = numpy.argsort(son_genuine_value, axis=0)son_value = son_population[:, son_genuine_index]return son_value,son_genuine_sortdef new_son(self,father_value, son_value,first_genuine_sort,son_genuine_sort):all_population = numpy.concatenate((father_value, son_value), axis=1)genuine_value = numpy.concatenate((first_genuine_sort, \son_genuine_sort), axis=0)genuine_sort = numpy.sort(genuine_value)genuine_index = numpy.argsort(genuine_value)father_son_value = all_population[:, genuine_index]first_genuine_sort = genuine_sort[0:self.genuine]father_value = father_son_value[:, 0:self.genuine]self.value.append(first_genuine_sort[0])return first_genuine_sort,father_valuedef main_function(self):population, son_population,father_value,first_genuine_sort = self.origin_data()# 开始主程序for gen in range(self.epoch):#交叉self.cross_function(son_population, father_value)#变异son_population = self.variation_function(son_population)#子代分析son_value,son_genuine_sort = self.son_genuine_analyze(son_population)##########产生新种群first_genuine_sort,father_value = self.new_son(father_value, son_value,first_genuine_sort,son_genuine_sort)print('第', gen + 1, '次循环完成!')passprint('最优个体为:',father_value,'\n最优解为:',self.value[-1])self.image_plot()def image_plot(self):plt.plot(range(self.epoch), self.value)plt.title('适应度曲线', fontproperties='stsong',fontsize=14)plt.xlabel('迭代步数', fontproperties='stsong',fontsize=14)plt.ylabel('函数结果', fontproperties='stsong',fontsize=14)# plt.text(0.1,-1,'函数结果1', fontproperties='stsong')plt.show()if __name__ == '__main__':start = genuine()start.main_function()