遗传算法【1】

博主在经历三周的学习和实践中,掌握了Python基础和遗传算法的基本思想。在实现遗传算法的过程中,遇到收敛速度过快及无法找到最优解的问题。通过分析,发现种群规模N、交叉概率Pc和变异概率Pm的选择对算法性能至关重要。通常,N取值在20~100之间,Pc在0.4~0.99,Pm在0.4~1.0(不使用交叉算子)或0.0001~0.5(使用交叉算子)。合适的终止条件也是优化算法的关键,可以依据最优解长时间不变来设定。尽管存在随机性,对于简单问题,100代的进化通常能得出满意解。
摘要由CSDN通过智能技术生成

历时n天的第一个程序终于结束了!虽然是仿照同学的写的,不过前前后后时间算起来三四周有好几整天都在这道题上。现在终于跑出结果,还是有很多收获的。给自己一个大拇指?【黄老师说了,搞科研要沉下来】

  1. python的一些基本用法熟悉了
  2. GA的基本思想也熟悉了

Q:代码完成后存在的问题就是收敛速度过快,而且无论进化多少代都找不到最优解。
A:需要考虑到参数选择问题,种群的规模N,交叉概率Pc,变异概率Pm,算法终止条件(进化代数)。

  1. N取值较小,可以提高运算速度,但是影响了种群的多样性,容易引起算法早熟。【对,我初始化是10忘记改了,结果收敛的特别快】
    N取值较大,提高算法搜索能力,增加算法计算量,降低算法效率。
    一般,20~100
  2. 交叉概率Pc,决定了进化过程中种群参与交叉的个体数目。
    Pc较小时发现新个体的速度太慢,Pc较大又会使搜索随机性太大。
    一般,0.4~0.99。自适应的交叉概率最理想。
  3. 变异概率Pm,增加种群的多样性。
    Pm较大,算法跳跃性太大;Pm较小,使算法聚焦于特别区域作局部搜索。
    一般,0.4~1.0【不使用交叉算子的话】;否则,0.0001~0.5。自适应的变异概率最理想。
  4. 终止条件,事先指定代数,可以在给定时限内找到相对满意解,但不一定找得到最优解。
    可以根据很长时间内最优解没有变化来终止算法。

以下是详细的题目要求、解答步骤以及代码:

"""
题目:
    max f(x1,x2) = 21.5 + x1 sin(4 PI x1) + x2 sin(20 PI x2)
    s.t.
    x1∈[-3.0, 12.1]
    x2∈[4.1, 5.8]
    E = 10^-4
解决:遗传算法
    1. 初始化种群:计算基因位数,生成初始个体,确定种群规模N,生成初始种群P,设置代数t=0
        二进制编码长度计算公式:(b - a) / 10^α + 1 ≤2^m
        math.log(num,base) base:默认为e; ceil 向上取整,floor 向下取整
        随机数生成方法:
            random.randint(a,b[,c]) : [a,b]的随机整数,c是步幅
            np.random.randint(a,b) : [a,b)前闭后开 (low=?,high=?,size=?,dtype=) size需要是整数或tuple,表示几行几列
            random.uniform(a,b)
    2. 计算个体适应度值,需要解码:y = a + (b - a)*x/(2^m-1),再代入f(x1,x2)中
    3. 轮盘赌选择,需要求出个体适应度比例p,再求出累计适应度区间q,随机生成N个(0,1)之间的数,得到所选择的个体编号
    4. 交叉,需要交叉算子pc,随机生成N/2个(0,1)之间的数,小于等于pc就交叉;
        父代个体通过两点交叉,生成两个(0,31)随机数作为交叉点,交换中间的gene得到两个子代个体
    5. 变异,对交叉产生的m个后代,随机生成m*33个(0,1)的随机数,判断变异位置进行变异
    6. 计算后代的适应度值,从generation∪offspring1∪offspring2中选N个,选出E个最好的直接保留到下一代,再从剩余中选出N-E个轮盘赌-->得到next_generation
"""
import math
import random
import heapq
import time
import matplotlib.pyplot as plt

start = time.time()

# ----------------------------初始化定义变量-------------------------
x1_left = -3.0  # x1,x2变量的范围
x1_right = 12.1
x2_left = 4.1
x2_right = 5.8
precision = 10 ** -4  # 精度要求
pc = 0.6  # 交叉概率
pm = 0.01  # 变异概率
N = 100  # 种群规模
T = 100  # 种群代数
E = int(N / 5)  # 精英保留数
ax = []	# plt的横坐标
ay = [] # plt的纵坐标


# -----------------------------计算编码位数---------------------------
def count_code_gene():
    x1_len = math.ceil(math.log((x1_right - x1_left) / precision + 1, 2))  # 18
    x2_len = math.ceil(math.log((x2_right - x2_left) / precision + 1, 2))  # 15
    # print(x1_len, x2_len)
    gene_length = x1_len + x2_len
    return x1_len, x2_len, gene_length


# ---------生成随机个体,编码[input:编码位数,output:个体gene]--------
def create_random_individual():
    gene_str = ''
    for i in range(gene_length):
        gene_str += str(random.randint(0, 1))
    # print(isinstance(gene_str,str))
    return gene_str


# ------初始化种群;input:种群规模,gene个数,output:初始种群-----------
def init_generation(population_size):
    next_generation = []
    for i in range(population_size):
        next_generation.append(create_random_individual())
    # print('初始化种群:', next_generation)
    return next_generation


# ----个体解码,input:个体和两变量长度,output:解码后的两个变量值--------
def decode(gene_str):
    x1 = int(gene_str[:x1_len], 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值