# ga


用遗传算法寻找函数最小值

函数库: TyGlobalOptimization

# 语法

x, fval, output = ga(func, lb, ub)
x, fval, output = ga(func, lb, ub, constraint_ueq, constraint_eq)
x, fval, output = ga(func, lb, ub, constraint_ueq, constraint_eq, options)
x, fval, output = ga(func, nvars, constraint_ueq, constraint_eq)
x, fval, output = ga(func, nvars, constraint_ueq, constraint_eq,options)
x, fval, output = ga(func, perm_size)
x, fval, output = ga(func, perm_size, options)

# 说明

x, fval, output = ga(func, lb, ub),求解带有边界约束的优化问题,其中 func 为目标函数,lb ,ub 分别为决策变量 x 的上下界。示例


x, fval, output = ga(func, lb, ub, constraint_ueq, constraint_eq),求解带有边界约束及不等式和等式约束的优化问题,其中 constraint_ueq ,constraint_eq 分别为不等式约束和等式约束。(如果不存在不等式或等式约束,令 constraint_ueq = () 或 constraint_eq = ())示例


x, fval, output = ga(func, lb, ub, constraint_ueq, constraint_eq, options),求解带有边界约束及不等式和等式约束的优化问题,使用 options 优化求解器参数。示例


x, fval, output = ga(func, nvars, constraint_ueq, constraint_eq),求解无边界约束的优化问题,其中 constraint_ueq ,constraint_eq 分别为不等式约束和等式约束,nvars 是 func 的维数(设计变量的数目)。(如果不存在不等式或等式约束,令 constraint_ueq = () 或 constraint_eq = ())示例


x, fval, output = ga(func, nvars, constraint_ueq, constraint_eq, options),求解无边界约束的优化问题,使用 options 优化求解器参数。


x, fval, output = ga(func, perm_size),求解序列规划问题,其中 perm_size 为序列长度。示例


x, fval, output = ga(func, perm_size, options),求解序列规划问题,使用 options 设定求解器优化选项。

# 示例

用遗传算法求解非光滑函数

当你运行该实例时,ps_example 函数被引入。绘制这个函数。

using TyGlobalOptimization
using TyPlot
using TyBase
using PyCall
@pyimport numpy as np
xi = range(-6, 2, 300)
yi = range(-4, 4, 300)
X, Y = np.meshgrid(xi, yi)
A = [reshape(X, :, 1) reshape(Y, :, 1)]
Z = ps_example(A)
Z = reshape(Z, size(X))
surf(X, Y, Z)
title("ps_example")
ylabel("x(1)")
xlabel("x(2)")

定义待求解问题。

function func(p)
    x1, x2 = p
    return ps_example([x1 x2])[1]
end
lb = [-6.0, -4.0]
ub = [2.0, 4.0]

执行求解。

x, fval, output = ga(func, lb, ub)

打印优化结果。

println("最优解 = $x")
println("最优值 = $fval")
最优解 = [-4.712389695810499, 3.305889503983774e-8]
最优值 = -1.9999999669405932

提示

由于遗传算法是随机的(即它会随机做出选择),因此每次运行遗传算法时都会得到略有不同的结果。如果您需要准确地重现结果,您可以在使用 ga 时包含选项 ga_options(;seed = 5489) 来固定随机数流。

具有等式和不等式约束的非光滑函数优化

定义待优化问题。

using TyGlobalOptimization
function func(p)
    x1, x2 = p
    return ps_example([x1 x2])[1]
end
lb = [-1.0, -3.0]
ub = [6.0, 8.0]

定义 2 个非线性约束,2 * x[1]^2 + x[2]^2 <= 3, (x[1] + 1)^2 - (x[2] / 2)^4 == 0,注意!等式或不等式约束需转化为标准形式:cons_eq(x) == 0 或 cons_ueq(x) <= 0。

cons_ueq1(x) = 2 * x[1]^2 + x[2]^2 - 3 
cons_eq1(x) = (x[1] + 1)^2 - (x[2] / 2)^4
constraint_ueq = (cons_ueq1,)
constraint_eq = (cons_eq1,)

执行求解。

x, fval, output = ga(func, lb, ub, constraint_ueq, constraint_eq)

打印优化结果。

println("最优解 = $x")
println("最优值 = $fval")
最优解 = [-0.9999999999625194, -1.2244276083101869e-5]
最优值 = 1.5000122442948234

检查等式和不等式约束是否被满足。

println(cons_ueq1(x))
-1.0
println(cons_eq1(x))     
2.0886183625410404e-33
无边界约束优化

定义待优化问题。

using TyGlobalOptimization
fun = x -> 1 + (x[1] - 1)^2 + (x[2] - 1)^4
nvars = 2

定义约束。

g = x -> x[1] + x[2] - 2
c = (g,)
ceq = ()

使用 ga 求解。

x,fval,output = ga(fun,nvars,c,ceq)

打印优化结果。

println("最优解 = $x")
println("最优值 = $fval")
最优解 = [1.0000079649236988, 0.9998653140085699]
最优值 = 1.0000000000634401

检查不等式约束是否被满足。

println(g(x))
-0.00012672106773115033
使用非默认参数优化

定义待优化问题。

using TyGlobalOptimization
function func(p)
    x1, x2 = p
    return ps_example([x1 x2])[1]
end
lb = [-1.0, -3.0]
ub = [6.0, 8.0]

设置优化选项。

options = ga_options(iterations=1000, draw_picture=true, seed=5489)

执行求解。

x, fval, output = ga(func, lb, ub, (), (), options)

打印优化结果。

println("最优解 = $x")
println("最优值 = $fval")
最优解 = [-1.0000000000000004, -7.312263929324362e-6]
最优值 = 1.500007312263929

绘制收敛图。

用遗传算法求解序列规划问题

定义待优化问题。

using TyGlobalOptimization

func(x) = sum(abs.(x .- (length(x):-1:1.0)))
perm_size = 10

执行求解。

x, fval, output = ga(func, perm_size)

打印优化结果。

println("最优解 = $x")
println("最优值 = $fval")
最优解 = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
最优值 = 0.0

# 输入参数

func-目标函数
函数名

func 为待求解问题的目标函数。func 接收一个向量 x,并返回一个标量值。

示例: func(x) = sum((x-[4,2]).^2)

数据类型: Function

nvars-变量的数目
正整数

变量的数目,指定为正整数。求解器传递长度为 nvars 到 func 的向量。

示例: nvars = 4

数据类型: Int

lb-决策变量下限
实数向量

决策变量的下限,即 x >= lb。

示例: lb = [-10,-Inf]

数据类型: Real

ub-决策变量上限
实数向量

决策变量的上限,即 x <= ub。

示例: ub = [Inf,10]

数据类型: Real

constraint_ueq-不等式约束
元组

不等式约束组。

示例: (cons_ueq1,) 表示约束cons_ueq1(x)<=0,可添加多个不等式约束。

数据类型: Function

constraint_eq-等式约束
元组

等式约束组。

示例: (cons_eq1,) 表示约束cons_eq1(x)==0,可添加多个等式约束。

数据类型: Function

options-优化选项
ga_options 函数的输出 | Struct

优化选项,指定求解器参数,由 ga_options 函数创建。 对于 ga, options 如下:

名称 含义 默认值
x_tol Real,若给定真实解,对真实解的容差。 1e-3
f_tol Real,若给定真实值,对真实值的容差。 1e-3
g_tol Real,若给定不等式约束,对不等式约束的容差。 1e-3
h_tol Real,若给定等式约束,对等式约束的容差。 1e-3
f_calls_limit Integer,目标函数最大评估次数。 200000
g_calls_limit Integer,不等式约束函数最大评估次数。 200000
h_calls_limit Integer,等式约束函数最大评估次数。 200000
time_limit Real,最大时间限制(以秒为单位)。 Inf
iterations Integer,最大迭代次数。 1000
store_convergence Bool,是否存储每次迭代状态。 true
debug Bool,是否报告每次迭代状态。 false
seed UInt,随机种子,非负整数。 rand(UInt)
f_optimum Real,真实最优值。 NaN
x_optimum Union{Vector,Real},真实最优解。 zeros(0)
N Integer,种群规模。 100
draw_picture Bool,是否绘制收敛图。 false
max_stall_generations Integer,为正整数值时生效,如果 max_stall_generations 代的最佳适应度函数值的平均相对变化小于或等于 f_tol,则算法停止。 -1
mutation_fcn Union{Nothing,Symbol,Tuple{Symbol,Real}},产生变异子代的函数。可选值为 :mutationpolynomial 或 :mutationslight,可以使用 (:mutationpolynomial,p) 为 mutationpolynomial 指定变异率 p。 nothing
crossover_fcn Union{Nothing,Symbol,Tuple{Symbol,Real}},用于创建交叉子代的函数。可选值为 :crossoversbx 或 :crossoveruniform ,指定交叉率 p 请使用 (:crossoversbx,p)。 nothing
display String,显示级别。可选值为 "off" 或 "iter"。 "off"

示例: options = ga_options(iterations=1000)。

perm_size-序列长度
正整数

序列长度。

示例: 10

数据类型: Int

# 输出参数

x-最优解
实数向量

最优解,作为实向量返回。

fval-最优值
实数

最优解对应的目标函数值,作为实数返回。一般来说,fval = func(x)。

output-其他输出信息
结构体

其他输出信息以 ga_output 结构体形式存储,包括 “迭代次数”,“函数评估次数”,“运行时间”,“停止状态”元素。output 各元素说明如下:

名称 含义
iterations Integer,迭代次数
f_calls Integer,函数评估次数
time_run Real,运行时间
termination_status String,停止状态

# 另请参阅

particleswarm | simulannealbnd | patternsearch