Python实现遗传算法
# -*- coding: utf-8 -*-
# author: 'boliang'
# date: 2018/3/13 8:46
import random
import numpy as np
import matplotlib.pyplot as plt
class Solution(object):
x_len = 2
best_eval = 0
def __init__(self, level=40, limit_l=-2, limit_r=2, mating_rate=0.88, mutate_rate = 0.1, cal_level=10000):
self.level = level
self.limit_l = limit_l
self.limit_r = limit_r
self.mating_rate = mating_rate
self.mutate_rate = mutate_rate
self.cal_level = cal_level
self.C = []
for i in range(level):
tmp = []
for j in range(self.x_len):
tmp.append(random.random() + random.randrange(limit_l, limit_r, 1))
self.C.append(tmp)
#评估函数
def __Eval__(self, C):
return C[0]*np.cos(2*np.pi*C[1]) + C[1]*np.sin(2*np.pi*C[0])
# return 1 / (sum(np.array(C)**2) + 1)
#计算最大适应值
def __get_best__(self):
return max(map(lambda C:self.__Eval__(C), self.C))
#选择
def __select__(self):
C_evals = list(map(lambda C:self.__Eval__(C), self.C))
eval_sum = sum(C_evals)
tmp_rates = list(map(lambda eval:eval/eval_sum, C_evals))
C_rates = list(map(lambda index:sum(tmp_rates[:index+1]), range(self.level)))
tmp_C = []
for i in range(self.level):
num = random.random()
for rate in C_rates:
if num < rate:
tmp_C.append(self.C[C_rates.index(rate)])
break
self.C = tmp_C
#交配
def __mating__(self):
select_mating_indexs = [cor for cor in range(self.level) if random.random() < self.mating_rate]
length = len(select_mating_indexs)
for i in range(0, length, 2):
if i+1 >= length:
break
else:
mating_bit = random.randint(0, self.x_len-1)
index_a = select_mating_indexs[i]
index_b = select_mating_indexs[i+1]
for ind in range(mating_bit, self.x_len):
self.C[index_a][ind], self.C[index_b][ind] = \
self.C[index_b][ind], self.C[index_a][ind]
#变异
def __mutate__(self):
for coord in range(self.level):
mutate_indexs = [cor for cor in range(self.x_len) if random.random() < self.mutate_rate]
for index in mutate_indexs:
self.C[coord][index] = random.random() + random.randrange(self.limit_l, self.limit_r, 1)
# 开始迭代
def run(self):
cal = self.cal_level
self.best_eval = self.__get_best__()
# 保存当前染色体适应值
tmps = []
while cal > 0:
# 选择
self.__select__()
#交配
self.__mating__()
#变异
self.__mutate__()
#重新评估染色体适应值,更新Best
tmp_best_eval = self.__get_best__()
self.best_eval = tmp_best_eval if tmp_best_eval > self.best_eval else self.best_eval
# print("第{0}次迭代后,染色体适应值为:{1}, 当前最大适应值为:{2}".format(self.cal_level-cal+1, tmp_best_eval, self.best_eval))
tmps.append(self.best_eval)
cal -= 1 #迭代次数减一
plt.plot([x for x in range(1, len(tmps)+1)], tmps)
plt.xlabel(u"times")
plt.ylabel(u"eval")
plt.show()
return self.get_eval()
def get_eval(self):
return self.best_eval
if __name__ == "__main__":
sol = Solution()
best_eval = sol.run()
print("迭代完成,染色体最好的适应值为:{0}".format(best_eval))
测试迭代后结果如下
迭代次数与适应值的关系图如下
Comments