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



测试迭代后结果如下


迭代次数与适应值的关系图如下