遗传算法GA

利用遗传算法求函数极值

在这里插入图片描述

引入numpy库

import numpy as np

定义相关参数:种群数量、交叉概率、变异概率、自变量的范围、DNA长度(一般=10)、循环代数

pop_size = 100  # 种群数量
PC=0.8 # 交叉概率
PM=0.01 #变异概率
X_max=2    #最大值
X_min=-1     #最小值
DNA_SIZE=10  #DNA长度与保留位数有关,2**10 当前保留3位小数点
N_GENERATIONS=1000 #循环代数

目标函数

def aim(x):
    return x*np.sin(10*np.pi*x)+1.0

生成二进制编码

pop = np.random.randint(2, size=(pop_size, DNA_SIZE)) 

解码

def decode(pop):
   return  pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) *(X_max-X_min)/ float(2**DNA_SIZE-1) +X_min

在这里插入图片描述

适应度:求最大值可以用原值作为适应度,为了防止产生0和负数加上一个偏移 1e-3 - np.min(pred)

def fitnessget(pred):
    return pred + 1e-3 - np.min(pred) 

选择

numpy.random.choice(a, size=None, replace=True, p=None)
从a(只要是ndarray都可以,但必须是一维的)中随机抽取数字,并组成指定大小(size)的数组
replace:True表示可以取相同数字,False表示不可以取相同数字
数组p:与数组a相对应,表示取数组a中每个元素的概率,默认为选取每个元素的概率相同。

def select(pop, fitness):           
    idx = np.random.choice(np.arange(pop_size), size=pop_size, replace=True,p=fitness/fitness.sum())
    return pop[idx]

交叉

np.astype() 转换numpy数组的数据类型

def change(parent, pop):
    if np.random.rand() < PC: #交叉概率
        i_ = np.random.randint(0, pop_size, size=1)
        cross_points = np.random.randint(0, 2, size=DNA_SIZE).astype(bool)
        parent[cross_points] = pop[i_, cross_points]
    return parent 

变异

def variation(child,pm):                 
    for point in range(DNA_SIZE):
        if np.random.rand() < pm:  #变异概率
            child[point] = 1 if child[point] == 0 else 0
    return child

循环迭代

for i in range(N_GENERATIONS):
    #解码
    X_value= decode(pop)
  
    #获取目标函数值
    F_values = aim(X_value)
    
    #获取适应值
    fitness = fitnessget(F_values)
	
	#开始,max=F_values最大的
    if(i==0): 
        max=np.max(F_values)
        max_DNA = pop[np.argmax(F_values)]
        
    if(max<np.max(F_values)):
        max=np.max(F_values)
        max_DNA=pop[np.argmax(F_values)]
     
    # 选择 
    pop = select(pop,fitness)
    
    # 交叉、变异,父=子
    pop_copy = pop.copy()
    for parent in pop:
        child = change(parent,pop_copy)
        child = variation(child,PM)
        parent= child
print("The maximum is:",max)
print("The DNA is:",max_DNA)
print("The X is:",decode(max_DNA))

在这里插入图片描述

整体代码

import numpy as np

pop_size = 10  # 种群数量
PC=0.8 # 交叉概率
PM=0.01 #变异概率
X_max=2    #最大值
X_min=-1     #最小值
DNA_SIZE=10  #DNA长度与保留位数有关,2**10 当前保留3位小数点
N_GENERATIONS=1000#迭代次数

#定义函数
def f(x):
    return x*np.sin(10*np.pi*x)+1.0
#解码
def decode(pop):
   return  pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) *(X_max-X_min)/ float(2**DNA_SIZE-1) +X_min
#计算适应度
def fitnessget(pred):
    return pred + 1e-3 - np.min(pred)
#选择 
def select(pop, fitness):        
    idx = np.random.choice(np.arange(pop_size), size=pop_size, replace=True,p=fitness/fitness.sum())
    return pop[idx]
#交叉
def change(parent, pop):
    if np.random.rand() < PC:    
        i_ = np.random.randint(0, pop_size, size=1)
        cross_points = np.random.randint(0, 2, size=DNA_SIZE).astype(bool)
        parent[cross_points] = pop[i_, cross_points]
    return parent 
#变异
def variation(child,pm):                  
    for point in range(DNA_SIZE):
        if np.random.rand() < pm:
            child[point] = 1 if child[point] == 0 else 0
    return child

pop = np.random.randint(2, size=(pop_size, DNA_SIZE)) 

for i in range(N_GENERATIONS):
    #解码
    X_value= decode(pop)
    
    #获取目标函数值
    F_values = f(X_value)
    
    #获取适应值
    fitness = fitnessget(F_values)

    if(i==0):
        max=np.max(F_values)
        max_DNA = pop[np.argmax(F_values)]
        
    if(max<np.max(F_values)):
        max=np.max(F_values)
        max_DNA=pop[np.argmax(F_values)]
        
    #选择
    pop = select(pop,fitness)
    pop_copy = pop.copy()
    for parent in pop:
        child = change(parent,pop_copy)
        child = variation(child,PM)
        parent= child
print("The maximum is:",max)
print("The DNA is:",max_DNA)
print("The X is:",decode(max_DNA))

请添加图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值