遗传算法解决二维和高维优化问题——基于Python

本文介绍了使用Python实现遗传算法来解决二维和高维优化问题,包括寻找最小值和最大值的场景,并提供了相应的代码示例。
摘要由CSDN通过智能技术生成

遗传算法解决二维和高维优化问题——基于Python

代码

1.二维问题:最优解为最小值

#-*- coding: utf-8 -*-

#遗传算法解决二维问题
#找最优解,这里是找最小值,因此需要对适应度函数做一下处理,即适应度函数为目标函数的倒数


import numpy as np
import matplotlib.pyplot as plt
import Scripts
import math
from pylab import mpl

#中文显示问题,黑体
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False


'''
遗传算法基本流程:
初始化种群
适应值评价,保存最优染色体
选择
交配
变异
重新评价适应值,更新最优染色体
满足终止条件则结束,否则继续选择过程
'''

#计算初始串长度
def Compute_Length(x, prec):

    length = 0.

    value = (x[1] - x[0]) * pow(10, prec) + 1.0
    length = np.log2(value)

    return length



#根据串长度创建初始种群
def Build_Init_Group(len0, len1, size):
    #先生成20位,再生成20位

    ref_list = []

    for i in range(size):

        initial_group = np.random.randint(0, 2, len0 + len1)
        # initial_group1 = np.random.randint(0, 2, len1)

        ref_list.append(initial_group)
        # ref_list1.append(initial_group1)
        #第二个子代的二进制表示在前
        # new_list = list(zip(ref_list1, ref_list0))
    #二维数组
    init_popu = np.array(ref_list)

    return init_popu


'''
计算解码值
init_popu:初始种群
'''
def Compute_Decode_Value(init_popu, x_range0, x_range1, length0, length1):

    # print(type(init_popu[0]))#ndarray
    # print(init_popu.size / init_popu[0].size)#ndarray
    #init_popu[0][0]表示第二个子代的二进制表示
    length_single = len(init_popu[0])
    ref_list0 = []
    ref_list1 = []

    #x和y的精度,用于计算解码值
    delta = [(x_range0[1] - x_range0[0]) / (pow(2, length0) - 1), (x_range1[1] - x_range1[0]) / (pow(2, length1) - 1)]

    '''
    计算每个个体的解码值
    先计算位和
    然后计算解码值存到数组里
    '''

    #遍历种群内所有个体   计算x和y的位和值
    for i in range(len(init_popu)):

        for j in range(0, 2):
            sum = 0.
            # x 的位和
            if j == 0:
                for k in reversed(range(length0, length_single)):
                    sum += init_popu[i][k] * pow(2, length_single - k - 1)
                    # print(init_popu[i][k], k, length_single, pow(2, length_single - k - 1))
                ref_list0.append(sum)

            # y 的位和
            if j == 1:
                for k in reversed(range(0, length1)):
                    sum += init_popu[i][k] * pow(2, length1 - k - 1)
                    # print(init_popu[i][k], k, length_single, pow(2, length1 - k - 1))
                ref_list1.append(sum)

    #计算x的解码值
    for x_num in range(len(ref_list0)):
        ref_list0[x_num] = x_range0[0] + delta[0] * ref_list0[x_num]
    #计算y的解码值
    for y_num in range(len(ref_list1)):
        ref_list1[y_num] = x_range1[0] + delta[1] * ref_list1[y_num]

    #构建二维解码值(x, y)
    new_list = list(zip(ref_list0, ref_list1))

    #构建二维解码值数组
    f = np.array(new_list)
    return f


#适应度函数
def Fittness_function(x, y):

    #这里取负值,因为要求最小解,所以取目标函数的负值选最大的
    # f1
    return 1. / (pow(x, 2) + pow(y, 2))
    # return (pow(x, 2) + pow(y, 2)) #求最大值

    # #f2
    # return 1. / (100 * pow((y - pow(x, 2)), 2) + pow((x - 1), 2))

    ##f3
    # return 1. / (((1 + pow((x + y + 1), 2)) + (19 - 14 * x + 3 * pow(x, 2) - 14 * y + 6 * x * y + 3 * pow(y, 2))) * (
    #     pow((30 + 2 * x - 3 * pow(y, 2)), 2) * (18 - 32 * x + 12 * pow(x, 2) + 48 * y - 32 * x * y + 27 * y)
    # ))

    # #f4
    # return 1. / (pow((pow(x, 2) + y - 11), 2) + pow((x + pow(y, 2) - 7), 2))

    # #f5
    # return 1. / (4 * pow(x, 2) + 2.1 * pow(x, 4) + (1/3) * pow(x, 6) + x * y - 4 * pow(y, 2) + 4 * pow(y, 4))

    # #f6
    # return 1.0 / (pow(x, 2) + pow(y, 2) - 0.3 * math.cos(3 * math.pi * x) + 0.3 * math.cos(4 * math.pi * y) + 0.3)

#目标函数
def Desti_function(x, y):

    #f1
    return pow(x, 2) + pow(y, 2)

    # #f2
    # return 100 * pow((y - pow(x, 2)), 2) + pow((x - 1), 2)

    ##f3
    # return ((1 + pow((x + y + 1), 2)) + (19 - 14 * x + 3 * pow(x, 2) - 14 * y + 6 * x * y + 3 * pow(y, 2))) * (
    #     pow(30 + 2 * x - 3 * pow(y, 2), 2) * (18 - 32 * x + 12 * pow(x, 2) + 48 * y - 32 * x * y + 27 * y)
    # )

    # #f4
    # return (pow((pow(x, 2) + y - 11), 2) + pow((x + pow(y, 2) - 7), 2))

    # #f5
    # return (4 * pow(x, 2) + 2.1 * pow(x, 4) + (1/3) * pow(x, 6) + x * y - 4 * pow(y, 2) + 4 * pow(y, 4))

    # #f6
    # return (pow(x, 2) + pow(y, 2) - 0.3 * math.cos(3 * math.pi * x) + 0.3 * math.cos(4 * math.pi * y) + 0.3)

#计算适应度
def Compute_Fitness(decode_value):

    ref = np.array([])

    for i in range(len(decode_value)):
        ref = np.append(ref, Fittness_function(decode_value[i][0], decode_value[i][1]))

    return ref


#轮盘赌选择
def Roulette_Select(fitness_value, init_pop):

    '''
    计算总体适应度F
    计算选择概率p_select
    计算累积概率q_select
    生成相应数量的[0, 1]之间的随机数
    若q_k-1<r<=q_k, 则选vk
    将选择出来的结果作为新的种群返回
    :param fitness_value: 适应度值
    '''
    #总体适应度
    F = sum(fitness_value)

    #计算选择概率
    p_select = fitness_value.copy()
    for i in range(len(fitness_value)):
        p_select[i] = p_select[i] / F

    #计算累积概率
    q_select = fitness_value.copy()
    for i in range(len(fitness_value)):
        q_select[i] = 0.


    for j in range(len(fitness_value)):
        for k in range(0, j+1):
            q_select[j] += p_select[k]


    #生成[0,1]之间的随机数
    rand_num = fitness_value.copy()
    for i in range(len(fitness_value)):
        rand_num[i] = 0.

    np.random.seed()#产生不固定的随机数

    rand_num = np.random.uniform(0, 1, len(rand_num))
    #比较判别,若q_k-1<r<=q_k, 则选vk
    new_list = []
    for num in range(len(rand_num)):
        for num_ in range(len(q_select)):

            if num_ == 0:
                if(rand_num[num] <= q_select[num_]):
                    new_list.append(init_pop[num_])
            else:
                if (rand_num[num] > q_select[num_ - 1] and rand_num[num] <= q_select[num_]):
                    new_list.append(init_pop[num_])

    #存放选择结果
    roulette_select_value = np.array(new_list)

    #还需要将选择出来的二进制表示也选择出来,用于后续交叉和变异
    return roulette_select_value

#交叉运算
def Cross_Select(select_pop, cross_prob):
    '''
    首先判断是否满足交叉条件,即根据给定交叉概率,为每个染色体产生随机概率,与给定交叉概率比较
    符合条件的则进行交叉操作
    :param select_pop: 选择出来的结果
    :return:返回交叉后的结果
    '''

    #为每个染色体产生(0, 1)内的交叉概率
    pop_cross_prob = np.random.uniform(0, 1, select_pop.shape[0])

    #判断哪些染色体可以进行交叉操作,哪些不可以,拆分成两部分
    cross_pop = select_pop[np.where(pop_cross_prob < cross_prob)]
    no_cross_pop = select_pop[np.where(pop_cross_prob >= cross_prob)]

    #开始交叉
    fo
  • 6
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值