Оптимизация стохастической целевой функции
Author
import Pkg
Pkg.add("Optim")
Pkg.add("Random")
Pkg.add("Plots")
using Optim, Random, Plots
# Инициализация исходных данных:
X0 = [2.5, -2.5] # Стартовая точка
LB = [-5.0, -5.0] # Нижняя граница
UB = [5.0, 5.0] # Верхняя граница
range = [LB[1] UB[1]; LB[2] UB[2]] # Диапазон
pts = 100 # Количество точек
iter = false # Показывать итерации
detailed = true # Выдодить подробный результат
# Гладкая целевая функция:
function smFcn(x)
#if any(x .< LB) || any(x .> UB)
# return Inf
#else
return x[1]^3 - x[2]^2 + 100 * x[2] / (10 + x[1])
#end
end
# Стохастическая целевая функция:
function stFcn(x)
peaknoise = 4.5 # Амплитуда шума
if any(x .< LB) || any(x .> UB)
return Inf
else
return x[1]^3 - x[2]^2 + 100 * x[2] / (10 + x[1]) + peaknoise * randn()
end
end
# Функция построения целевой функции:
function buildFcn(Fcn,range)
span = diff(range', dims=1) ./ (pts - 1)
X = range[1, 1]:span[1]:range[1, 2]
Y = range[2, 1]:span[2]:range[2, 2]
values = zeros(Float64, pts * pts, 1)
k = 1
for i in 1:pts
for j in 1:pts
values[k] = Fcn([X[i], Y[j]])
k += 1
end
end
values = reshape(values, pts, pts)
return X, Y, values
end
# Оптимизация гладкой целевой функции методами IPNewton и GradientDescent
# аналоги метода interior-point функции fmincon в Matlab
smResultIP = optimize(smFcn, LB, UB, X0, IPNewton(), Optim.Options(show_trace = iter))
smResultGD = optimize(OnceDifferentiable(smFcn, X0), LB, UB, X0, Fminbox(GradientDescent()), Optim.Options(show_trace = iter))
Random.seed!(0)
# Оптимизация стохастической целевой функции методами IPNewton и GradientDescent
# аналоги метода interior-point функции fmincon в Matlab
#stResult = optimize(OnceDifferentiable(stFcn, X0), LB, UB, X0, Fminbox(GradientDescent()), Optim.Options(show_trace = true))
stResultIP = optimize(stFcn, LB, UB, X0, IPNewton(), Optim.Options(show_trace = iter))
stResultGD = optimize(OnceDifferentiable(stFcn, X0), LB, UB, X0, Fminbox(GradientDescent()), Optim.Options(show_trace = iter))
# Оптимизация стохастической целевой функции методами NelderMead и SimulatedAnnealing
# аналог функции patternsearch в Matlab
stResultNM = optimize(stFcn, LB, UB, X0, NelderMead(), Optim.Options(show_trace = iter))
stResultSA = optimize(stFcn, LB, UB, X0, SimulatedAnnealing(), Optim.Options(show_trace = iter))
# Вывод результатов
if detailed
println("\nГладкая целевая функция:\n")
println("\nМетод IPNewton")
println("Найденная точка минимума: ", Optim.minimizer(smResultIP))
println("Значение функции в найденной точке минимума: ", Optim.minimum(smResultIP),"\n")
println("\nМетод GradientDescent")
println("Найденная точка минимума: ", Optim.minimizer(smResultGD))
println("Значение функции в найденной точке минимума: ", Optim.minimum(smResultGD),"\n")
end
plotlyjs()
# Отображение гладкой функции
smX, smY, smVal = buildFcn(smFcn, range)
smFig = surface(smX, smY, smVal; alpha = 0.9, c=:viridis, legend=:bottomright, legendfontsize = 7, colorbar = false, title = "Гладкая целевая функция", titlefont = font(12))
plot!(smFig, camera=(-19, -4))
scatter!(smFig, [X0[1]], [X0[2]], [smFcn(X0)+30], color=:red, markersize = 2, label = "Стартовая точка", seriestype = :scatter3d)
scatter!(smFig, [Optim.minimizer(smResultIP)[1]], [Optim.minimizer(smResultIP)[2]], [Optim.minimum(smResultIP)], color =:magenta, marker = (:diamond, 2), label = "Метод IPNewton", seriestype =:scatter3d)
scatter!(smFig, [Optim.minimizer(smResultGD)[1]], [Optim.minimizer(smResultGD)[2]], [Optim.minimum(smResultGD)], color =:green, marker = (:diamond, 2), label = "Метод GradientDescent", seriestype =:scatter3d)
display(smFig)
# Вывод результатов
if detailed
println("\n\nСтохастическая целевая функция - неподходящие методы:\n")
println("\nМетод IPNewton")
println("Найденная точка минимума: ", Optim.minimizer(stResultIP))
println("Значение функции в найденной точке минимума: ", Optim.minimum(stResultIP),"\n")
println("\nМетод GradientDescent")
println("Найденная точка минимума: ", Optim.minimizer(stResultGD))
println("Значение функции в найденной точке минимума: ", Optim.minimum(stResultGD),"\n")
println("\n\nСтохастическая целевая функция - подходящие методы:\n")
println("\nМетод NelderMead")
println("Найденная точка минимума: ", Optim.minimizer(stResultNM))
println("Значение функции в найденной точке минимума: ", Optim.minimum(stResultNM),"\n")
println("\nМетод SimulatedAnnealing")
println("Найденная точка минимума: ", Optim.minimizer(stResultSA))
println("Значение функции в найденной точке минимума: ", Optim.minimum(stResultSA),"\n")
end
# Отображение стохастической функции
stX, stY, stVal = buildFcn(stFcn, range)
stFig = surface(stX, stY, stVal; alpha = 0.9, c=:viridis, legend=:bottomright, legendfontsize = 7, colorbar = false, title="Стохастическая целевая функция", titlefont = font(12))
plot!(stFig, camera=(-19, -4))
scatter!(stFig, [X0[1]], [X0[2]], [stFcn(X0)+30], color=:red, markersize = 2, label = "Стартовая точка", seriestype = :scatter3d)
scatter!(stFig, [Optim.minimizer(stResultIP)[1]], [Optim.minimizer(stResultIP)[2]], [Optim.minimum(stResultIP)], color=:yellow, marker = (:diamond, 2), label = "Метод IPNewton", seriestype =:scatter3d)
scatter!(stFig, [Optim.minimizer(stResultGD)[1]], [Optim.minimizer(stResultGD)[2]], [Optim.minimum(stResultGD)], color=:cyan, marker = (:diamond, 2), label = "Метод GradientDescent", seriestype =:scatter3d)
scatter!(stFig, [Optim.minimizer(stResultSA)[1]], [Optim.minimizer(stResultSA)[2]], [Optim.minimum(stResultSA)], color=:green, marker = (:diamond, 2), label = "Метод SimulatedAnnealing", seriestype =:scatter3d)
scatter!(stFig, [Optim.minimizer(stResultNM)[1]], [Optim.minimizer(stResultNM)[2]], [Optim.minimum(stResultNM)], color=:blue, marker = (:diamond, 2), label = "Метод NelderMead", seriestype =:scatter3d)
display(stFig)