2026a
# 创建帕累托前沿
本示例展示如何使用多目标遗传算法创建帕累托前沿的一组点, 并与理论上的精确点进行比较。
# 问题描述
本示例考虑的问题有 2 个目标函数。
# 定义待优化问题
using TyPlot
using TyBase
using TyGlobalOptimization
using TyOptimization
# 目标函数
f1(x) = x[1] .^ 4 + x[2] .^ 4 + x[1] .* x[2] - (x[1] .^ 2) .* (x[2] .^ 2) - 9 .* x[1] .^ 2
f2(x) = x[1] .^ 4 + x[2] .^ 4 + x[1] .* x[2] - (x[1] .^ 2) .* (x[2] .^ 2) + 3 .* x[2] .^ 3
mymulti3(x) = [f1(x), f2(x)]
objcon = packfcn(mymulti3, (), ())
# 目标个数
nobj = 2
# 边界
lb = [-50.0, -50.0]
ub = [50.0, 50.0]
# 执行求解,并绘制帕累托前沿
options = gamultiobj_options(draw_picture=true)
PF, PS, output = gamultiobj(objcon, nobj, lb, ub, options)
# 计算理论上帕累托前沿的精确点
通过以下 mymulti4 函数来获取理论上帕累托前沿的精确点,它计算了 2 个目标函数的梯度。
function mymulti4(x)
gg = [4 * x[1]^3 + x[2] - 2 * x[1] * (x[2]^2) - 18 * x[1], x[1] + 4 * x[2]^3 - 2 * (x[1]^2) * x[2]]
gf = gg + [18 * x[1], 9 * x[2]^2]
mout = gf[1] * gg[2] - gf[2] * gg[1]
return mout
end
接下来,使用 fzero 定位梯度平行的点,即 mout=0 的点。
gamultiobj(objcon, nobj, lb, ub, options)
hold("on")
myfun1(t) = mymulti4([t, -3.15])
a1 = [fzero(myfun1, [2, 3])[1] -3.15]
plot(mymulti3(a1)[1], mymulti3(a1)[2], "*r")
for jj in collect(range(-3.125, -1.89, 50))
myfun2(t) = mymulti4([t, jj])
a2 = [fzero(myfun2, [2, 3])[1] jj]
plot(mymulti3(a2)[1], mymulti3(a2)[2], "*r")
end
legend("Gamultiobj", "True")
hold("off")
从图中可以看到 gamultiobj 求解器在目标函数空间中找到了分布稍广的点。
# 在决策变量空间中绘制解的等高线图。
在决策变量空间中绘制解决方案、理论上的最佳帕累托曲线和两个目标函数的等高线图。
figure(3)
a = [fzero(myfun1, [2, 3])[1] -3.15]
for jj in collect(range(-3.125, -1.89, 50))
myfun2(t) = mymulti4([t, jj])
global a = [a; [fzero(myfun2, [2, 3])[1] jj]]
end
x, y = meshgrid2(1.9:0.01:3.1, -3.2:0.01:-1.8)
mydata = mymulti3([x, y])
myff = sqrt.(mydata[1] .+ 39) # 更好地展示等高线
mygg = sqrt.(mydata[2] .+ 28) # 更好地展示等高线
contour(x, y, mygg, 50)
hold("on")
contour(x, y, myff, 50)
plot(PF[1, :], PF[2, :], "*r") # gamultiobj 求解器得到的帕累托解集
plot(a[:, 1], a[:, 2], "-k") # 最佳帕累托曲线
xlabel("x[1]")
ylabel("x[2]")
hold("off")
上图中,红星表示 gamultiobj 求解器得到的帕累托解集,黑线表示理论上的最佳帕累托曲线。