每天学点算法->进化策略->遗传算法简单例子解读

假设草原上有一群斑马,这群斑马里面,有些斑马跑的比较快,有的跑的慢,而狮子每次捕猎能抓到跑的慢的斑马,那么经过一代代的繁衍,根据达尔文进化论,留下的大部分斑马都是跑的比较快的。进化策略也是基于这优胜略汰,适者生存的套路,通过模拟一个种群的进化过程,逐步优化参数,最终使得目标函数达到最优.

在这个例子中

目标函数:max=sin(10*x)*x + cos(2*x)*x ; x属于[0,5]

 

由此我们的整个逻辑过程就变成了:

1.创建一个种群,种群中有100个个体(数量自定义),每个个体有10个长度的基因,基因我们这里使用0和1编码

2.将种群中每个个体的基因由2进制翻译成10进制数,带入目标函数,得到的值作为个体的适应度

3.随机保留适应度高的个体,随机去除适应度低的个体,优胜略汰

4.种群经过自然选择后,每个个体都随机与一个个体进行配对,生成孩子,孩子分别从父母中获取一半的基因.

5.生成的孩子进行随机突变,

6.将生成的子代作为新一代种群

7.重复2-6过程100次(繁衍100代)

 

 

由于过程比较简单,下面直接上例子代码(注释比较全,对上上面过程应该也很容易)


# coding: utf-8
"""
基础遗传算法
1.初始化种群
2.对种群select
3.对种群crossover
4.循环2,3
"""
import numpy as np
import matplotlib.pyplot as plt
import time


class GAB:
    def __init__(self,pop_size=100,dna_size=10,n_generation=200,cross_rate=0.8,mutation_rate=0.003,x_bound=[0,5]):
        self.pop_size=pop_size
        self.dna_size=dna_size
        self.n_generation=n_generation
        self.cross_rate=cross_rate
        self.mutation_rate=mutation_rate
        self.x_bound=x_bound
        
        #初始化种群
        self.pop=np.random.randint(2,size=(self.pop_size,self.dna_size))
        
    
    """
    主循环部分
    2.对种群select
    3.对种群crossover
    4.循环2,3
    """
    def training(self):
        plt.ion()       # something about plotting
        x = np.linspace(*self.x_bound, 200)
        plt.plot(x, self.F(x))
        for genneration in range(self.n_generation):
            
            F_values = self.F(self.translateDNA(self.pop))

            try:
                sca.remove()
            except:
                print("error")
                time.sleep(6)
            
            sca = plt.scatter(self.translateDNA(self.pop), F_values, s=200, lw=0, c='red', alpha=0.5); plt.pause(0.05)
            
            pop_better=self.select(self.pop)
            pop_next=self.crossover(pop_better)
            pop_next=self.mutation(pop_next)
            self.pop[:]=pop_next[:]
        plt.ioff(); plt.show()
        return self.pop
    
    """
    进行自然选择
    1.获取适应度
    2.根据适应度选择个体集合
    """
    def select(self,pop):
        fitness=self.get_fitness(pop)
        better_index=np.random.choice(range(len(pop)),size=len(pop),replace=True,p=fitness**2/(fitness**2).sum())
        print("better index:")
        print(better_index)
        return pop[better_index]
    

    """
    获取适应度
    1.减去方程中的最小值,确保适应度都是正数,随后我们需要用这个适应度来作为select种群的概率
    """
    def get_fitness(self,pop): 
        F_value=self.F(self.translateDNA(pop))
        return F_value + 1e-3 - np.min(F_value)

    """
    一条自定义的方程,用于反映适应度和画图
    """
    def F(self,x): return np.sin(10*x)*x + np.cos(2*x)*x
    
    """
    1.把dna当成二进制数
    2.将2进制数转化为10进制,并限制在0到self.x_bound[1]区间内
    """
    def translateDNA(self,pop): return pop.dot(2 ** np.arange(self.dna_size)[::-1]) / float(2**self.dna_size-1) * self.x_bound[1]
    
    """
    1.在经过自然选择的种群里
    2.一个个体father 与 种群中随机选出一个个体mother进行随机交换部分dna
    """
    def crossover(self,pop_better):
        pop=pop_better.copy()
        for i in range(len(pop_better)):
            #父本
            father=pop[i]
            
            #母本
            mother_index=np.random.choice(range(len(pop_better)),size=1)
            mother=pop_better[mother_index][0]
            
            #交叉配对的点
            cross_points=np.random.randint(0,2,size=len(father),dtype=np.bool)
          
            #子代
            father[cross_points]=mother[cross_points]
        return pop
    
    def mutation(self,pop):
        for i in range(len(pop)):
            child=pop[i]
            for j in range(len(child)):
                if np.random.rand()<self.mutation_rate:
                    child[j]=1 if child[j]==0 else 0
        return pop
            


gab=GAB(100)
print(gab.pop)
print(gab.get_fitness(gab.pop))
print(gab.crossover(gab.select(gab.pop)))





gab.training()

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值