Algorithm Optimization for Machine Learning (1)


foreword

Geatpy is a high-performance practical evolutionary algorithm toolbox, which can be used to solve single-objective optimization, multi-objective optimization, complex constraint optimization, combinatorial optimization, mixed coding evolutionary optimization, etc. Various algorithms are encapsulated inside, including genetic algorithm, differential evolution algorithm, swarm particle algorithm, simulated annealing algorithm, etc.

Geatpy documentation: http://geatpy.com/index.php/%e6%80%bb%e8%a7%88/

Install:

pip install geatpy

Geatpy architecture description

Overall, Geatpy2 consists of two parts: the toolbox kernel function (kernel layer) and the object-oriented evolutionary algorithm framework (framework layer). Among them, the object-oriented evolutionary algorithm framework mainly has four categories: Problem class, Algorithm algorithm template class, Population population class and PsyPopulation multi-chromosomal population class. A UML diagram looks like this:
insert image description here

  • Problem
    The Problem class defines some information related to the problem, such as the name of the problem, the dimension M of the optimization goal, the number of decision variables Dim, the ranges of the decision variables, the boundaries of the decision variables, etc. maxormins is a Numpy array row vector that records whether each objective function is minimized or maximized, where an element of 1 indicates that the corresponding objective is the minimum objective; -1 indicates that the corresponding objective is the maximum objective. For example, M=3, maxormins=array([1,-1,1]), which means that there are three optimization goals, the first and third are the minimization goals, and the second is the maximization goal. varTypes is a row vector that records the type of decision variable. An element of 0 indicates that the corresponding decision variable is a continuous variable; an element of 1 indicates that the corresponding variable is a discrete variable. The objective function to be solved is defined in the function of aimFunc(). The calReferObjV() function is used to calculate or read the reference value of the objective function (generally, the optimal value of the theoretical objective function is used as the reference value); getReferObjV() is a function that has been implemented in the Problem parent class, it first tries Read the objective function value reference data in a specific folder, if it cannot be read, call calReferObjV() to calculate.
  • Algorithm
    The Algorithm class is the core class for evolutionary algorithms. It not only stores some parameters related to the evolutionary algorithm, but also implements the specific evolutionary algorithm in its inherited class.
  • Population
    The Population class is a class that represents a population. A population contains many individuals, and each individual has a chromosome (if you want to use multiple chromosomes, use multiple populations and associate the corresponding individuals of each population). In addition to the chromosome, each individual has a decoding matrix Field (or commonly known as a region descriptor) to identify how the chromosome should be decoded to obtain the phenotype, and also has its corresponding objective function value and fitness. The population class is a class that uniformly stores the data of all individuals. For example, Chrom inside is a matrix that stores all individual chromosomes of the population, and each row of it corresponds to an individual chromosome; ObjV is a matrix of objective function values, each row corresponds to all objective function values ​​of an individual, and each column corresponds to an objective.
  • PsyPopulation
    The PsyPopulation class is a population class that inherits Population and supports multi-chromosomal mixed coding. A population contains many individuals, and each individual has multiple chromosomes. The Chroms list is used to store all chromosome matrices (Chrom); the Encodings list stores the encoding method (Encoding) corresponding to each chromosome; the Fields list stores the decoding matrix (Field) corresponding to each chromosome. EncoIdxs is a list whose elements indicate which variable each chromosome encodes. For example, EncoIdxs = [[0], [1,2,3,4]], indicating that there are 5 variables in total, of which the first variable is encoded as the first sub-chromosome; the last 4 variables are encoded as the second sub-chromosome .

These algorithm templates realize the evolutionary operation on the population by calling the evolutionary algorithm library functions provided by the Geatpy toolbox, and record the relevant information in the evolution process
insert image description here
. By instantiating the operator class to call the low-level operation function, you can take advantage of object-oriented programming to make it more convenient to modify some parameters passed into the low-level operation function. Currently, the built-in "operator classes" include "recombination operator class" and "mutation operator class". Users can bypass the modification of the underlying low-level operation functions and directly implement new operators such as adaptive reorganization and mutation operators by adding "operator classes".

Instructions for solving function optimize in Geatpy tool

optimize(algorithm, seed=None, prophet=None, 
         verbose=None, drawing=None, outputMsg=True,
         drawLog=True, saveFlag=True, dirName=None, 
         **kwargs)

Parameter Description:

    algorithm : 算法类的引用。

    seed      : int  - 随机数种子。

    prophet   : <class: Population> / Numpy ndarray - 先验知识。可以是种群对象,
                      也可以是一组或多组决策变量组成的矩阵(矩阵的每一行对应一组决策变量)。默认为None。

    verbose   : bool - 控制是否在输入输出流中打印输出日志信息。
                       该参数将被传递给algorithm.verbose。
                       如果algorithm已设置了该参数的值,则调用optimize函数时,可以不传入该参数。
                       默认为None。

    drawing   : int  - 算法类控制绘图方式的参数,
                       0表示不绘图;
                       1表示绘制最终结果图;
                       2表示实时绘制目标空间动态图;
                       3表示实时绘制决策空间动态图。
                       该参数将被传递给algorithm.drawing。
                       如果algorithm已设置了该参数的值,则调用optimize函数时,可以不传入该参数。
                       默认为None。

    outputMsg : bool - 控制是否输出结果以及相关指标信息。默认为True。

    drawLog   : bool - 用于控制是否根据日志绘制迭代变化图像。默认为True。

    saveFlag  : bool - 控制是否保存结果。默认为True。

    dirName   : str  - 文件保存的路径。当缺省或为None时,默认保存在当前工作目录的'result of job xxxx-xx-xx xxh-xxm-xxs'文件夹下。
                       默认为None。

输出参数:
    result    : dict - 一个保存着结果的字典。内容为:
                       {'success': True or False,  # 表示算法是否成功求解。
                        'stopMsg': xxx,  # 存储着算法停止原因的字符串。
                        'optPop': xxx,  # 存储着算法求解结果的种群对象。如果无可行解,则optPop.sizes=0。optPop.Phen为决策变量矩阵,optPop.ObjV为目标函数值矩阵。
                        'lastPop': xxx,  # 算法进化结束后的最后一代种群对象。
                        'Vars': xxx,  # 等于optPop.Phen,此处即最优解。若无可行解,则Vars=None。
                        'ObjV': xxx,  # 等于optPop.ObjV,此处即最优解对应的目标函数值。若无可行解,ObjV=None。
                        'CV': xxx,  # 等于optPop.CV,此处即最优解对应的违反约束程度矩阵。若无可行解,CV=None。
                        'startTime': xxx,  # 程序执行开始时间。
                        'endTime': xxx,  # 程序执行结束时间。
                        'executeTime': xxx,  # 算法所用时间。
                        'nfev': xxx,  # 算法评价次数
                        'gd': xxx,  # (多目标优化且给定了理论最优解时才有) GD指标值。
                        'igd': xxx,  # (多目标优化且给定了理论最优解时才有) IGD指标值。
                        'hv': xxx,  # (多目标优化才有) HV指标值。
                        'spacing': xxx # (多目标优化才有) Spacing指标值。
                        }

1. Genetic Algorithm Elite Retention Strategy

1. The concept of single-objective genetic algorithm elite retention strategy

The genes in the Genetic Algorithm do not necessarily truly reflect the essence of the problem to be solved, so the genes are not necessarily independent of each other. If they are simply crossed, it is likely to destroy a better combination , In this way, the purpose of accumulating good genes is not achieved, but the original good genes are destroyed. The elite retention strategy can prevent the optimal individuals from being destroyed by hybridization.
Elite retention strategy : it is proposed for the genetic algorithm. For the genetic algorithm, whether it can converge to the global optimal solution is the primary problem. The idea of ​​De Jong's strategy is to copy the best individual (called elite individual elitist) that has appeared so far in the evolution process of the group to the next generation without pairing crossover. This selection operation is also called copy .

The main reasons why the standard genetic algorithm cannot converge globally:

  • (1) Using the proportional selection method, due to the existence of statistical errors, the selection is based on the generated random numbers, which may incorrectly reflect the selection of individual fitness, which may lead to the elimination of individuals with high fitness;

  • (2) Crossover and mutation operators may destroy the high-order, long-distance, and high-average fitness schema implicit in the individual, which may lead to the optimal individual in the current population Loss occurs in the next generation population, and this phenomenon of optimal individual loss will appear repeatedly in the evolution process.

De Jong defines the elite retention strategy method as follows:

Assuming that at the tth generation, a(t) in the population is the optimal individual. Let A(t+1) be the new generation group, if there is no individual better than a(t) in A(t+1), add a(t) into A(t+1) as A( The n+1th individual of t+1), where n is the size of the group.

In order to keep the size of the group constant, if elite individuals are added to the new generation group, the individuals with the worst fitness value in the new generation group will be eliminated.

  • One approach is to put elite individuals into the population, that is, the population size is N+1. One way to maintain the population size is to replace the elite individuals with the worst individuals in the population.

The elite individual is the individual with the highest fitness value searched by the genetic algorithm so far in the evolution of the population, and it has the best genetic structure and excellent characteristics. The advantage of adopting elite retention is that in the evolution process of genetic algorithm, the best individuals that have appeared so far will not be lost and destroyed by selection, crossover and mutation operations. The elite-retaining strategy plays a significant role in improving the global convergence ability of the standard genetic algorithm. Rudolph has theoretically proved that the standard genetic algorithm with elite-reserving is globally convergent.

2. Example of SEGA algorithm for solving single-objective genetic problems

Question 1:
insert image description here
Range of Quantities.

Steps of genetic algorithm SEGA for enhanced elite retention strategy :

  • The first step: first define the objective function
  • Step Two: Create a Question
  • Step 3: Build the Algorithm
  • Step 4: Call the optimize() function to solve

Use the SEGA algorithm in the Geatpy tool to solve problem 1:

import geatpy as ea
import numpy as np

# 构建问题
r = 1  # 目标函数需要用到的额外数据
@ea.Problem.single
# 让目标函数的传入参数是一个Numpy ndarray类型的一维数组,它的实际含义是种群的某个个体对应的决策变量。
def evalVars(Vars):  # 定义目标函数(含约束)
    f = np.sum((Vars - r) ** 2)  # 计算目标函数值(函数表达式)
    x1 = Vars[0]
    x2 = Vars[1]
    # 先把约束条件转成线性约束条件(等式右边是0)
    CV = np.array([(x1 - 0.5)**2 - 0.25,
                    (x2 - 1)**2 - 1])  # 不等式约束(计算违反约束程度)
    return f, CV                       # 返回目标函数值和违反约束程度

problem = ea.Problem(name='增强精英保留策略的遗传算法',
                        M=1,  # 目标维数
                        maxormins=[1],  # 目标最小最大化标记列表,1:最小化该目标;-1:最大化该目标
                        Dim=5,  # 决策变量维数(个数为5)
                        varTypes=[0, 0, 1, 1, 1], # 决策变量的类型列表,0:实数;1:整数。0表示对应的决策变量是连续型变量;为1表示对应的是离散型变量。
                        lb=[-1, 1, 2, 1, 0],  # 决策变量下界
                        ub=[1, 4, 5, 2, 1],  # 决策变量上界
                        evalVars=evalVars)
# 构建算法
algorithm = ea.soea_SEGA_templet(problem,
                                 # Encoding='RI实整数编,NIND=20设定了种群有20个个体。
                                    ea.Population(Encoding='RI', NIND=20),
                                    MAXGEN=50,  # 最大进化代数。
                                    logTras=1,  # 表示每隔多少代记录一次日志信息,0表示不记录。
                                    trappedValue=1e-6,  # 单目标优化陷入停滞的判断阈值。
                                    maxTrappedCount=10)  # 进化停滞计数器最大上限值。
# 求解
res = ea.optimize(algorithm, seed=1, verbose=True, drawing=1, outputMsg=True, drawLog=False, saveFlag=True, dirName='result')

The output is:
insert image description here

==================================================================================
gen|  eval  |    f_opt    |    f_max    |    f_avg    |    f_min    |    f_std    
----------------------------------------------------------------------------------
 0 |   20   | 9.18566E+00 | 9.18566E+00 | 9.18566E+00 | 9.18566E+00 | 0.00000E+00 
 1 |   40   | 5.78235E+00 | 9.18566E+00 | 8.33483E+00 | 5.78235E+00 | 1.47368E+00 
 2 |   60   | 5.78235E+00 | 1.01857E+01 | 8.44530E+00 | 5.78235E+00 | 1.56014E+00 
 3 |   80   | 5.18566E+00 | 9.18566E+00 | 7.10178E+00 | 5.18566E+00 | 1.70646E+00 
 4 |  100   | 2.18566E+00 | 5.78235E+00 | 5.31974E+00 | 2.18566E+00 | 1.00074E+00 
 5 |  120   | 2.18566E+00 | 5.71252E+00 | 4.47875E+00 | 2.18566E+00 | 1.38039E+00 
 6 |  140   | 2.18566E+00 | 5.18566E+00 | 2.88560E+00 | 2.18566E+00 | 1.09847E+00 
 7 |  160   | 2.02037E+00 | 2.18566E+00 | 2.15260E+00 | 2.02037E+00 | 6.61145E-02 
 8 |  180   | 2.00000E+00 | 2.18565E+00 | 2.02762E+00 | 2.00000E+00 | 3.65244E-02 
 9 |  200   | 2.00000E+00 | 2.02037E+00 | 2.01625E+00 | 2.00000E+00 | 8.12936E-03 
 10|  220   | 2.00000E+00 | 2.02037E+00 | 2.00908E+00 | 2.00000E+00 | 9.96122E-03 
 11|  240   | 1.00000E+00 | 2.00000E+00 | 1.95000E+00 | 1.00000E+00 | 2.17945E-01 
 12|  260   | 1.00000E+00 | 2.00000E+00 | 1.80000E+00 | 1.00000E+00 | 4.00000E-01 
 13|  280   | 1.00000E+00 | 2.00000E+00 | 1.45000E+00 | 1.00000E+00 | 4.97494E-01 
 14|  300   | 1.00000E+00 | 1.00000E+00 | 1.00000E+00 | 1.00000E+00 | 0.00000E+00 
 15|  320   | 1.00000E+00 | 1.00000E+00 | 1.00000E+00 | 1.00000E+00 | 0.00000E+00 
 16|  340   | 1.00000E+00 | 1.00000E+00 | 1.00000E+00 | 1.00000E+00 | 0.00000E+00
 
Execution time: 0.013827323913574219 s
Evaluation number: 340
The best objective value is: 1.0
The best variables are: 
1.0	1.0	2.0	1.0	1.0
  • Encoding='RI' in the above code indicates that the chromosomes of the modified population are encoded by 'RI', that is, "real integer mixed encoding", referred to as "real integer encoding". There are also 'P' encoding (permutation encoding, which can make the corresponding variables different from each other), 'BG' encoding (binary/gray code encoding).

3. There are several ways to define the objective function in the SEGA algorithm

1. Method 1

    def aimFunc(pop):  # 定义目标函数(含约束)
        Vars = pop.Phen
        pop.ObjV = np.sum((Vars - r)**2, 1,
                          keepdims=True)  # 计算目标函数值,赋值给种群对象的ObjV属性
        x1 = Vars[:, [0]]  # 把Vars的第0列取出来
        x2 = Vars[:, [1]]  # 把Vars的第1列取出来
        pop.CV = np.hstack([(x1 - 0.5)**2 - 0.25,
                            (x2 - 1)**2 - 1])  # 计算违反约束程度值,赋值给种群对象的CV属性

illustrate:

The objective function here is defined as aimFunc, not evalVars.
The input of aimFunc(pop) is a population object pop.
pop.Phen is the phenotype matrix of the population, which is equivalent to the decision variable matrix. It is a two-dimensional array of Numpy ndarray, each row represents a set of decision variable values.
pop.ObjV is the matrix of objective function values ​​for the population. It is a two-dimensional array of Numpy ndarray, each row represents a set of objective function values.
pop.CV is the constraint violation degree matrix for the population. It is a two-dimensional array of Numpy ndarray, each row represents a set of violation degree values.

2. Method 2

    def evalVars(Vars):  # 定义目标函数(含约束)
        ObjV = np.sum((Vars - r)**2, 1, keepdims=True)  # 计算目标函数值
        x1 = Vars[:, [0]]  # 把Vars的第0列取出来
        x2 = Vars[:, [1]]  # 把Vars的第1列取出来
        CV = np.hstack([(x1 - 0.5)**2 - 0.25, (x2 - 1)**2 - 1])  # 计算违反约束程度
        return ObjV, CV  # 返回目标函数值矩阵和违反约束程度矩阵

illustrate:

The objective function here is defined as evalVars, not aimFunc.
Difference:
aimFunc(pop) is passed in a population object.
And evalVars(Vars) is passed in a Numpy ndarray two-dimensional array. All elements of each row represent a set of decision variables.
The function evalVars can have one or two return values. The first return value represents the objective function value matrix; the second return value represents the constraint violation degree matrix.
If there are no constraints, just return a return value. So the usage is:
ObjV = evalVars(Vars) or ObjV, CV = evalVars(Vars)

3. Method three

def evalVars(Vars):  # 定义目标函数(含约束)
        f = []  # 存储目标函数值
        CV = []  # 存储违反约束程度
        for i in range(Vars.shape[0]):  # 遍历每一组决策变量,计算对应的目标函数值
            f.append(np.sum((Vars[i, :] - r)**2))  # 用Vars[i, :] 取出每一组决策变量
            x1 = Vars[i, 0]
            x2 = Vars[i, 1]
            CV.append(np.array([(x1 - 0.5)**2 - 0.25, (x2 - 1)**2 - 1]))
        return np.vstack(f), np.vstack(CV)  # 返回目标函数值矩阵和违反约束程度矩阵

illustrate:

The difference from the above is that this case uses a loop to calculate the value of the objective function and the degree of violation of constraints for each individual.

4. Method four

    @ea.Problem.single
    def evalVars(Vars):  # 定义目标函数(含约束)
        f = np.sum((Vars - r)**2)  # 计算目标函数值
        x1 = Vars[0]
        x2 = Vars[1]
        CV = np.array([(x1 - 0.5)**2 - 0.25, (x2 - 1)**2 - 1])  # 计算违反约束程度
        return f, CV

illustrate:

In this case, the objective function evalVars is marked with the decorator single, so that the objective function only passes in a set of decision variables.
At this time, the objective function only needs to calculate the objective function value corresponding to this group of variables and the value of the degree of constraint violation.
Usage:
ObjV = evalVars(Vars) – if no constraints or ObjV, CV = evalVars(Vars) – if constraints
Note:
After adding the decorator single, the incoming parameter Vars of evalVars is no longer a Numpy ndarray two-dimensional array, but is a Numpy ndarray 1D array.
When setting the return value:
the return value ObjV can be assigned as a Numpy ndarray one-dimensional array, or a scalar (when there is only one optimization target).
The return value CV can be assigned as a Numpy ndarray one-dimensional array, or it can be a scalar (when there is only one optimization objective).
It is worth noting that
the return value obtained by calling evalVars(Vars) will be corrected to a Numpy ndarray two-dimensional array by the single decorator.
That is, ObjV obtained by ObjV = evalVars(Vars) or: ObjV and CV obtained by ObjV, CV = evalVars(Vars), both are Numpy ndarray two-dimensional arrays.

2. NSGA2 Algorithm Dual Objective Optimization Problem

Introduction to NSGA2 multi-objective genetic algorithm: https://blog.csdn.net/q15615725386/article/details/119521206

1. NSGA2 algorithm concept

The NSGA algorithm is based on the genetic algorithm and based on the Pareto optimal concept. The main difference between the NSGA algorithm and the standard genetic algorithm is that it performs a fast non-dominated sort on the individuals before the selection operation, which increases the probability of excellent individuals being retained, and the selection, crossover, mutation and other operations are no different from the basic genetic algorithm.

  1. The NSGA algorithm still has certain shortcomings, which are mainly reflected in the following aspects:
  • (1) The algorithm has a large amount of calculation. The relationship between the computational complexity of the NSGA algorithm and the number of populations N and the number of objective functions m is T = O(mN3). When the population size is large and the number of objective functions is large, it takes a long time.

  • (2) No meritocracy was applied. The retention probability of outstanding individuals has not been improved through the elite strategy, so the execution speed of the program cannot be accelerated.

  • (3) It is necessary to artificially specify the sharing radius R, which requires very high experience.

  1. The NSGA2 algorithm is mainly improved in the following aspects:
  • (1) The NSGA-II algorithm uses the fast non-dominated sorting method, which reduces the computational complexity of the algorithm from O(mN3) to O(mN2), which greatly reduces the computational time of the algorithm.

  • (2) The elite retention strategy is adopted, and the non-dominated sorting is performed after merging the parent individuals and the offspring individuals, so that the search space becomes larger, and the individuals with higher priority are selected in order when generating the next generation parent population, and The crowding degree is used to select among individuals of the same level (excluding poor individuals), which ensures that excellent individuals have a greater probability of being retained.

  • (3) The fitness sharing strategy that needs to specify the sharing radius is replaced by the method of crowding, and it is used as the standard for selecting excellent individuals among individuals of the same level, which ensures the diversity of individuals in the population, and is beneficial for individuals to be able to be in the entire interval. Perform selection, crossover, and mutation.

  1. Elite retention strategy
    The NSGA-II algorithm introduces an elite retention strategy to achieve the purpose of retaining excellent individuals and eliminating inferior individuals. The elitist strategy expands the scope of screening when generating the next generation of individuals by mixing parent and offspring individuals to form a new population. Analyze the example shown in the figure. In the figure, P represents the parent population, and the number of individuals in it is n, and Q represents the offspring population. The specific steps are as follows:
  • (1) Merge the parent population and the offspring population to form a new population. Then perform non-dominated sorting on the new population. In this example, the population is divided into 6 Pareto levels.

  • (2) Carry out the generation of new parents, first put the non-dominant individuals with Pareto rank 1 into the new parent set, and then put the individuals with Pareto rank 2 into the new parent population, so as to analogy.

  • (3) If all the individuals with rank k are put into the new parent set, the number of individuals in the set is less than n, and after all the individuals with rank k+1 are put into the new parent set, the number of individuals in the set If the number of individuals is greater than n, calculate the degree of crowding for all individuals at level k+1 and arrange all individuals in descending order according to the degree of crowding, and then eliminate all individuals whose level is greater than k+1. In this example, it can be seen that k is 2, so the individuals with Pareto level 3 are calculated and sorted in descending order, and the individuals with levels 4~6 are all eliminated.

  • (4) Put the individuals in level k+1 into the new parent set one by one according to the order arranged in step 2, until the number of individuals in the parent set is equal to n, and the remaining individuals are eliminated.
    insert image description here

2. NSGA2 algorithm solves the dual objective optimization problem example

Question 2 :
insert image description here
#Use the NSGA2 algorithm to solve the dual-objective optimization problem steps

  • The first step: inherit the parent class (ea.Problem)
  • Step 2: Call the constructor of the parent class
  • Step 3: Create the objective function. The objective function evalVars is defined, which overrides evalVars() in the Problem class. Note that this name cannot be changed casually.
    Geatpy's Problem class provides definitions of two objective functions, evalVars and aimFunc. The former (evalVars) is a new way of writing after Geatpy2.7.0. It passes in the decision variable matrix Vars and needs to return the corresponding objective function value matrix ObjV and constraint degree matrix CV (if the problem to be solved has no constraints, you can just returns the objective function matrix). The latter (aimFunc) is the traditional way of writing, it passes in a population object, and does not need to return a value.
  • Step 4: Instantiate the class object
  • Step 5: Call the optimize() function to solve

Use the NSGA2 algorithm in the Geatpy tool to solve problem 2:

class MyProblem(ea.Problem):  # 继承Problem父类(geatpy封装好的类)
    def __init__(self):
        name = 'NSGA2算法'  # 初始化name(函数名称,可以随意设置)
        M = 2  # 优化目标个数(两个x)
        maxormins = [1] * M  # 初始化maxormins(目标最小最大化标记列表,1:最小化该目标;-1:最大化该目标)
        Dim = 1  # 初始化Dim(决策变量维数)
        varTypes = [0]  # 初始化varTypes(决策变量的类型,0:实数连续型变量;1:整数离散型变量)
        lb = [-10]  # 决策变量下界(自定义个上下界搜索)
        ub = [10]  # 决策变量上界
        lbin = [1]  # 决策变量下边界(0表示不包含该变量的下边界,1表示包含)
        ubin = [1]  # 决策变量上边界(0表示不包含该变量的上边界,1表示包含)
        # 调用父类构造方法(_init_)完成实例化,后跟参数
        ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb, ub, lbin, ubin)

    def evalVars(self, Vars):  # 目标函数
        f1 = Vars ** 2 # 第一个目标函数
        f2 = (Vars - 2) ** 2 # 第二个目标函数
        ObjV = np.hstack([f1, f2])  # 计算目标函数值矩阵
        CV = -Vars ** 2 + 2.5 * Vars - 1.5  # 构建违反约束程度矩阵(需要转换为小于,反转一下)
        return ObjV, CV

# 实例化问题对象
problem = MyProblem()
# 构建算法
algorithm = ea.moea_NSGA2_templet(problem,
                                  # RI编码,种群个体100
                                    ea.Population(Encoding='RI', NIND=100),
                                    MAXGEN=200,  # 最大进化代数
                                    logTras=1 # 表示每隔多少代记录一次日志信息,0表示不记录。
                                    ) 
# 求解
res = ea.optimize(algorithm, seed=1, verbose=False, drawing=1, outputMsg=True, drawLog=False, saveFlag=False, dirName='result')

输出为:
insert image description here
Execution time: 0.10509157180786133 s
Evaluation number: 20000
The number of non-dominated solutions is: 100
hv: 0.83201
spacing: 0.02100

3. Multi-objective optimization algorithm NSGA3

ZDT1, DTLZ1 (DTLZ1-7), WFG1, etc. Taking DTLZ1 as an example, the DTLZ1 problem object can be instantiated directly through ea.benchmarks.DTLZ1(). The code to solve DTLZ1 with NSGA3 algorithm is as follows:

Geatpy2.7.0 archives the implemented test problems into the benchmarks folder, so you can directly modify the function behind the benchmarks to test a certain problem

problem = ea.benchmarks.DTLZ1()  # 生成问题对象
# 构建算法
algorithm = ea.moea_NSGA3_templet(problem,
                                  ea.Population(Encoding='RI', NIND=100),
                                  MAXGEN=500,  # 最大进化代数。
                                  logTras=1)  # 表示每隔多少代记录一次日志信息,0表示不记录。
# 求解
res = ea.optimize(algorithm, verbose=True, drawing=1, outputMsg=True, drawLog=True, saveFlag=True, dirName='result')

输出为:
insert image description here
Execution time: 0.5562167167663574 s
Evaluation number: 45500
The number of non-dominated solutions is: 91
gd: 0.00020
igd: 0.02062
hv: 0.84156
spacing: 0.00028
insert image description here
insert image description here
insert image description here
insert image description here


Summarize

Geatpy tools:

Guess you like

Origin blog.csdn.net/ex_6450/article/details/126142650